I have a global vector of vector of structs of this form:
vector<vector<stackEntry>> shadowStacksVector
where the idea is to have a vector<stackEntry>
per thread.
In the thread start function I do the following:
vector<stackEntry> sstack;
shadowStacksVector.push_back(sstack);
tdata->shadowStack = &(shadowStacksVector.back());
where tdata
is a struct containing the thread local storage.
What I would like to do is to have, for each thread, a reference to the vector of stack entries, so that each thread can add or remove elements to its own stack.
Conceptually I believe that push_back
does a copy of the element so I thought that this should have worked. However, when I try to add/remove elements from tdata->shadowStack
my program crashes.
On the contary, if I replace the vector of vectors with an array like this:
vector<stackEntry> shadowStacksVector[256]
everything works fine.
Containers are not thread safe, you need to create thread-safe sections of code to work with them in several threads. Use std::mutex
or std::atomic
to create thread-safe sections of code.
Neither std::vector
nor std::list
is thread-safe. Your std::vector
fails probably because when you push_back new value its allocated memory can do reallocate and all elements can move in other part of memory, so your old pointers can point on old broken data. If you will use shadowStacksVector->reserve
(MAX_INTERNAL_VECTORS_COUNT) at start vector's memory won't be reallocating when you do push_back, it guarantees that std::vector reserved memory for MAX_INTERNAL_VECTORS_COUNT and next reallocate can happen after you will push_back MAX_INTERNAL_VECTORS_COUNT+1 element.
std::list
don't need to reallocate all his elements, because its elements can store in different parts of memory, it allocates memory for each element every time you do push_back, so old pointers are point on the same place of memory.