【发布时间】:2016-05-01 23:36:43
【问题描述】:
几周以来,我一直在尝试修复在任务调度应用程序中可能粗略地使用 void* 转换的问题。请注意,我没有收到编译器错误,但调度程序在几个小时后崩溃(出于某种未知原因)。考虑程序中的以下代码 sn-ps:
在main:
CString* buffer = new CString(temp);
parameters.set("jobID", (void *) buffer);
runJob(parameters);
另外,VGridTaskParam 类如下:
class VGridTaskParam{
map<CString, void *> p; // maps from CString to a pointer that is not known
public:
void * get(CString name){
return p[name]; // returns the map value of the name which is an unknown pointer
}
void set(CString name, void * data){
p[name] = data; // sets the mpa value given a particular key
}
};
runJob(VGridTaskParam parameters) 函数中的一些工作片段是:
void runJob(VGridTaskParam parameters)
{
CString JIDstr; // job ID string
//get job ID as CString
CString* pJID = (CString*)parameters.get("jobID");
JIDstr = CString(*pJID);
delete pJID; ******************************
}
一些问题:最后delete 行(标有几个星号)是否删除了在主程序中创建的内存分配?在这种情况下,我是否需要使用 void* 强制转换。请注意,每当我运行作业时,我都会生成一个新线程。有人可以建议解决此问题的潜在方法吗?我应该看什么来解决这个问题?
【问题讨论】:
-
如果它在几个小时后崩溃而不是立即崩溃,那么您可能内存不足,因此您对
delete的直觉是正确的。诚然,这里看起来不错,所以我认为问题出在runJob的其他地方或它调用的方法中。也许有更多的内存分配,或者您的CString*可能以另一种方式被释放,导致双重删除。 -
我不能说确切的错误是什么,但我可以说动态分配对象并要求手动删除它是要求内存泄漏。如果可能的话,我的建议是将参数数据结构的保持值类型从 (void *) 更改为 unique_ptr
(或者甚至只是简单的旧的按值存储的 Cstring),以便所需的删除是自动为您完成的(当然,删除您对删除的明确调用)。这可能会解决问题。 -
我看不出有任何理由在这里使用
void*强制转换,但是,它们似乎并没有导致崩溃。我建议从 C++ 程序中删除 void* 算术,看看你是否需要任何动态内存管理——也可能删除它。这将使代码更清晰,更容易推理,因此可以更容易地找到错误(如果它仍然存在)。 -
在您的
get和set方法中,如果name不作为键存在,您将在地图中创建孔。std::map::operator[ ]创建一个条目,如果它不存在的话。而是使用map::find()或map::count()来确定该项目是否存在。
标签: c++ memory-management memory-leaks void-pointers