删除指针有时会导致堆损坏 [英] Deleting pointer sometimes results in heap corruption
问题描述
我有一个使用自定义线程池类运行的多线程应用程序。
I have a multithreaded application that runs using a custom thread pool class. The threads all execute the same function, with different parameters.
这些参数通过以下方式提供给threadpool类:
These parameters are given to the threadpool class the following way:
// jobParams is a struct of int, double, etc...
jobParams* params = new jobParams;
params.value1 = 2;
params.value2 = 3;
int jobId = 0;
threadPool.addJob(jobId, params);
一旦线程没有做任何事情,它会获取下一个参数并运行作业函数。我决定照顾删除threadpool类中的参数:
As soon as a thread has nothing to do, it gets the next parameters and runs the job function. I decided to take care of the deletion of the parameters in the threadpool class:
ThreadPool::~ThreadPool() {
for (int i = 0; i < this->jobs.size(); ++i) {
delete this->jobs[i].params;
}
}
但是,这样做时,腐败错误:
However, when doing so, I sometimes get a heap corruption error:
指定给RtlFreeHeap的无效地址
Invalid Address specified to RtlFreeHeap
奇怪的是,在一种情况下,它完美地工作,但在另一个程序崩溃与这个错误。我尝试在其他地方删除指针:在执行作业函数后的线程(我得到相同的堆腐败错误)或作业函数本身结束(在这种情况下没有错误)。
The strange thing is that in one case it works perfectly, but in another program it crashes with this error. I tried deleting the pointer at other places: in the thread after the execution of the job function (I get the same heap corruption error) or at the end of the job function itself (no error in this case).
我不明白如何删除相同的指针(我检查,地址是相同的)从不同的地方更改任何东西。这与多线程的事实有关吗?
I don't understand how deleting the same pointers (I checked, the addresses are the same) from different places changes anything. Does this have anything to do with the fact that it's multithreaded?
我有一个关键部分来处理对参数的访问。我不认为问题是关于同步访问。无论如何,析构函数只有在所有线程完成后才被调用,我不会在任何其他地方删除任何指针。是否可以自动删除指针?
I do have a critical section that handles the access to the parameters. I don't think the problem is about synchronized access. Anyway, the destructor is called only once all threads are done, and I don't delete any pointer anywhere else. Can pointer be deleted automatically?
至于我的代码。作业列表是一个结构的队列,由作业的ID(用于以后能够获取特定作业的输出)和参数组成。
As for my code. The list of jobs is a queue of a structure, composed of the id of a job (used to be able to get the output of a specific job later) and the parameters.
getNextJob()
在每次完成执行上一个作业时由线程调用(它们有一个指向ThreadPool的指针)。
getNextJob()
is called by the threads (they have a pointer to the ThreadPool) each time they finished to execute their last job.
void ThreadPool::addJob(int jobId, void* params) {
jobData job; // jobData is a simple struct { int, void* }
job.ID = jobId;
job.params = params;
// insert parameters in the list
this->jobs.push(job);
}
jobData* ThreadPool::getNextJob() {
// get the data of the next job
jobData* job = NULL;
// we don't want to start a same job twice,
// so we make sure that we are only one at a time in this part
WaitForSingleObject(this->mutex, INFINITE);
if (!this->jobs.empty())
{
job = &(this->jobs.front());
this->jobs.pop();
}
// we're done with the exclusive part !
ReleaseMutex(this->mutex);
return job;
}
推荐答案
:为什么要使用指针?
class Params
{
int value1, value2; // etc...
}
class ThreadJob
{
int jobID; // or whatever...
Params params;
}
class ThreadPool
{
std::list<ThreadJob> jobs;
void addJob(int job, const Params & p)
{
ThreadJob j(job, p);
jobs.push_back(j);
}
}
没有新的,删除或指针...显然有些的实施细节可能被搁置,但你得到的总体情况。
No new, delete or pointers... Obviously some of the implementation details may be cocked, but you get the overall picture.
这篇关于删除指针有时会导致堆损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!