concurrent_vector invalid data

c++, concurrency, concurrent-vector, multithreading, visual-c++

Solution

The problem is using of `concurrent_vector::size()` which is not fully thread-safe as you can get reference to not yet constructed elements (where memory contains garbage). Microsoft PPL library (which provides it in `concurrency::` namespace) uses Intel TBB implementation of `concurrent_vector` and TBB Reference says:

`size_type size() const` | Returns: Number of elements in the vector. The result may include elements that are allocated but still under construction by concurrent calls to any of the growth methods.

Please see my blog for more explanation and possible solutions.

In TBB, the most reasonable solution is to use `tbb::zero_allocator` as underlying allocator of `concurrent_vector` in order to fill newly allocated memory with zeroes before size() will count it too.

concurrent_vector<datanode*, tbb::zero_allocator<datanode*> > lst;

Then, the condition `if (nd)` will filter out not-yet-ready elements.

Problem

using : VC++ 2013 ``` concurrency::concurrent_vector<datanode*> dtnodelst ``` Occasionally when I do `dtnodelst->at(i)` .... I am getting an invalid address (0XCDCD.. ofc) which shouldn't be the case cause after I do push back, I never delete or remove any of the itms ( even if I delete it should have returned the deleted old address... but I am not ever deleting so that is not even the case ) ``` dtnodelst itm = new dtnodelst (); .... dtnodelst->push_back(itm); ``` any ideas on what might be happening ? p.s. I am using windows thread pool. some times .. I can do 8million inserts and find and everything goes fine .... but sometimes even 200 inserts and finds will fail. I am kind of lost. any help would be awesomely appreciated!! thanks and best regards actual code as an fyi p.s. am I missing something or is it pain in the ass to past code with proper formatting ? I remember it being auto align before ... -_- ``` struct datanode { volatile int nodeval; T val; }; concurrency::concurrent_vector<datanode*> lst inline T find(UINT32 key) { for (int i = 0; i < lst->size(); i++) { datanode* nd = lst->at(i); //nd is invalid sometimes if (nd) if (nd->nodeval == key) { return (nd->val); } } return NULL; } inline T insert_nonunique(UINT32 key, T val){ datanode* itm = new datanode(); itm->val = val; itm->nodeval = key; lst->push_back(itm); _updated(lst); return val; } ```

Original source