Этот вопрос является уточнением этот, который был в другом направлении, чем ожидалось.
В моем многопоточном приложении основной поток создает параметры и сохраняет их:
typedef struct {
int parameter1;
double parameter2;
float* parameter3;
} jobParams;
typedef struct {
int ID;
void* params;
} jobData;
std::vector<jobData> jobs;
// main thread
for (int i = 0; i < nbJobs; ++i) {
jobParams* p = new jobParams;
// fill and store params
jobData data;
data.ID = i;
data.params = p;
jobs.push_back(data);
}
// start threads and wait for their execution
// delete parameters
for (int i = 0; i < jobs.size(); ++i) {
delete jobs[i].params;
}
Затем каждый поток получает указатель на набор параметров и вызывает с ним функцию задания:
// thread (generic for any job function and any type of params)
jobData* job = main->getNextParams();
jobFunction(job->ID, job->params);
Все это принимает void* в качестве аргумента, чтобы иметь возможность использовать любую структуру для параметров, но затем функция задания возвращает его обратно к правильной структуре:
void* jobFunction(void* param) {
jobParams* params = (jobParams*) param;
// do stuff
return 0;
}
Моя проблема в следующем: если я delete params
в конце jobFunction()
, он работает отлично. Однако я бы предпочел, чтобы об удалении заботились потоки или основной поток, чтобы мне не приходилось помнить об удалении параметров для каждого jobFunction()
, который я пишу.
Если я попытаюсь выполнить delete params
сразу после вызова jobFunction()
в тредах или даже в основном потоке, убедившись, что все потоки выполнены (и, следовательно, параметры больше не нужны), я получаю ошибку повреждения кучи:
HEAP[prog]: указан неверный адрес для RtlFreeHeap (02E90000, 03C2EE38)
Я использую Visual Studio 2008 Pro и поэтому не могу использовать valgrind или другие инструменты *nix для отладки. Все обращения к основному потоку из «дочерних потоков» синхронизируются с помощью мьютекса, так что проблема не в том, что я дважды удаляю одни и те же параметры.
На самом деле, используя средство просмотра памяти VS, я знаю, что память, указанная указателем jobParams, не изменяется между концом jobFunction() и точкой, где я пытаюсь ее удалить (ни в основном потоке, ни в «дочерних потоках»). ").
Я добавил определение обеих структур, а также то, как я хотел бы удалить параметры.