Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
2464 Discussions

unexplained behavior of stl vector local to tbb task

Sreekumar_Natarajan
241 Views
Hello,
I am trying to use STL vector as local to a task but it is getting corrupted while an 'int' array doesn't seem to have the same problem. I expect vector to behave exactly sameas the arraybecause they are local to the taskand hence no concurrent access. I added a copy ctor to the taskstill no difference. I also triedindexing the vector as my_vec but produced the same output.

I am using TBB '2.1.009_64' on Linux with gcc (3.4.2). Any help will be greatly appreciated.

- vec val => 5277928 array val => 1
- vec val => 0 array val => 2
- vec val => 3 array val => 3
- vec val => 4 array val => 4
- vec val => 5 array val => 5




//! Test stl Vec
struct MyTask: public task {
int my_int_arr[MAX_SIZE];
vector my_vec;
MyTask( int n) : my_vec() { }

task* execute() {
int i =0;
for ( myMapIterator mIt = myMap.begin() ; mIt != myMap.end();++mIt)
{
printf("\\t- key => %s val => %i \\n",mIt->first, mIt->second);
my_vec.push_back(mIt->second);
my_int_arr[i++] = mIt->second;
}
return 0;
}
};

int main()
{
myMap["foo1"] = 1;
myMap["foo2"] = 2;
myMap["foo3"] = 3;
myMap["foo4"] = 4;
myMap["foo5"] = 5;
task_scheduler_init scheduler_init(3);
int n = 16;
task_list list;
MyTask * QIT = new(task::allocate_root()) MyTask( n );
list.push_back(*QIT);
task::spawn_root_and_wait(list);
int i =0;
for( vector::iterator gIt = QIT->my_vec.begin(); gIt != QIT->my_vec.end(); ++gIt)
{
printf("\\t- vec val => %i \\t array val => %i \\n",*gIt,QIT->my_int_arr[i++]);
}
delete QIT;
return 0;
}

output:

- vec val => 5277928 array val => 1
- vec val => 0 array val => 2
- vec val => 3 array val => 3
- vec val => 4 array val => 4
- vec val => 5 array val => 5


0 Kudos
2 Replies
RafSchietekat
Valued Contributor III
241 Views
Hmm, why doesn't "delete QIT" pose a problem, because surely the referent MyTask no longer exists?

(Added for clarity, but apparently in a race with #2) The program is printing values from objects that no longer exist because spawn_root_and_wait() has deleted the MyTask, with only the vector accidentally partially overwritten. You should be able to verify that by doing something conspicuous in a MyTask destructor. If you want to preserve the values, e.g., give the task a pointer to something that survives it, or recycle the task. But again, I do not see how "delete QIT" would not crash the program...
0 Kudos
Alexey-Kukanov
Employee
241 Views

Once executed, usually a TBB task is automatically deleted.So in your case the vector is destroyed, and the array data are not overwritten by mere luck. And as Raf said you should not delete the task explicitly.

0 Kudos
Reply