【发布时间】:2010-11-20 21:47:19
【问题描述】:
此问题是对this one 的改进,其方向与预期不同。
在我的多线程应用程序中,主线程创建参数并存储它们:
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;
}
我的问题如下:如果我在jobFunction() 的末尾加上delete params,它可以完美运行。但是,我更愿意让线程或主线程负责删除,这样我就不必记住删除我编写的每个 jobFunction() 的参数。
如果我在线程中调用jobFunction() 之后尝试delete params,甚至在确保所有线程都已完成(因此不再需要参数)之后在主线程中尝试,我得到堆损坏错误:
HEAP[prog]: 指定给 RtlFreeHeap(02E90000, 03C2EE38) 的地址无效
我使用的是 Visual Studio 2008 Pro,因此无法使用 valgrind 或其他 *nix 工具进行调试。 “子线程”对主线程的所有访问都是使用互斥锁同步的,所以问题不在于我两次删除相同的参数。
实际上,通过使用 VS 内存查看器,我知道 jobParams 指针指向的内存在 jobFunction() 结束和我尝试删除它的点之间(无论是在主线程中还是在“子线程”)。
我添加了两个结构的定义,以及我想要删除参数的方式。
【问题讨论】:
-
我们可以看看你如何删除作业->参数吗?你不应该有任何问题做你的建议(我自己从来没有遇到过类似的问题)。我们还可以看到 jobData 类/结构定义吗?
-
我都添加了。如果我只是删除 jobFunction() 中的参数,它可以工作,但我想在主线程中执行它,如图所示。
-
棘手,一切看起来都不错。既然您说如果您尝试从主线程中删除就会出现问题,那么连接代码中可能存在一些错误。是否可以在问题文本中显示其中一些代码?
-
加入代码是什么意思?我等待线程完成的代码?
-
是的,我就是这个意思。
标签: c++ multithreading pointers memory-management heap-memory