Добавление элементов в глобальный вектор векторов структур - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть глобальный вектор вектора структур этой формы:

vector<vector<stackEntry>> shadowStacksVector

, где идея состоит в том, чтобы иметь vector<stackEntry> на поток.

В функции запуска потока я делаю следующее:

vector<stackEntry> sstack;
shadowStacksVector.push_back(sstack);
tdata->shadowStack = &(shadowStacksVector.back());

где tdata - структура, содержащая локальное хранилище потока. Я хотел бы иметь для каждого потока ссылку на вектор элементов стека, чтобы каждый поток мог добавлять или удалять элементы в своем собственном стеке. Концептуально я считаю, что push_back делает копию элемента, поэтому я подумал, что это должно сработать. Однако, когда я пытаюсь добавить / удалить элементы из tdata->shadowStack, моя программа падает.

На этой странице, если я заменю вектор векторов на массив, подобный этому:

vector<stackEntry> shadowStacksVector[256]

все отлично работает.

1 Ответ

0 голосов
/ 28 апреля 2018

Контейнеры не являются поточно-ориентированными, вам нужно создавать поточно-ориентированные разделы кода для работы с ними в нескольких потоках. Используйте std::mutex или std::atomic для создания многопоточных разделов кода.

Ни std::vector, ни std::list не являются поточно-ориентированными. Ваш std::vector завершается неудачно, вероятно, потому что когда вы нажимаете новое значение push_back, его выделенная память может перераспределяться, и все элементы могут перемещаться в другую часть памяти, поэтому ваши старые указатели могут указывать на старые поврежденные данные. Если вы будете использовать shadowStacksVector->reserve (MAX_INTERNAL_VECTORS_COUNT) в начале, память вектора не будет перераспределяться, когда вы выполняете push_back, это гарантирует, что std :: vector зарезервированная память для MAX_INTERNAL_VECTORS_COUNT и последующее перераспределение могут произойти после того, как вы нажмете MAX_INTERNAL_VECTORS_COUNT из MAX_INTERNAL_VECTORS_COUNT. 1009 *

std::list не нужно перераспределять все его элементы, потому что его элементы могут храниться в разных частях памяти, он выделяет память для каждого элемента каждый раз, когда вы выполняете push_back, поэтому старые указатели указывают на одно и то же место памяти .

...