关于 C++ 的问题内存分配和删除
我遇到了一个严重的错误。当我对对象层次结构顶部的对象调用delete(希望导致删除其子对象)时,我的程序退出并得到以下信息:
*** glibc detected *** /home/mossen/workspace/abbot/Debug/abbot: double free or corruption (out): 0xb7ec2158 ***
后面是看起来像某种内存转储的内容。我已经搜索过此错误,从我收集的信息来看,当您尝试删除已删除的内存时,似乎会发生此错误。不可能,因为我的代码中只有一个地方尝试进行此删除。这是古怪的部分:它不会在调试模式下发生。有问题的代码:
Terrain::~Terrain()
{
if (heightmap != NULL) // 'heightmap' is a Heightmap*
{
cout << "heightmap& == " << heightmap << endl;
delete heightmap;
}
}
我已经注释掉了高度图析构函数中的所有内容,但仍然出现此错误。发生错误时,
heightmap& == 0xb7ec2158
打印 。在调试模式下,我可以缓慢地单步执行代码并
heightmap& == 0x00000000
打印出来,并且没有错误。如果我注释掉“删除高度图;”线,错误永远不会发生。上面的析构函数是从另一个析构函数调用的(单独的类,没有虚拟析构函数或类似的东西)。高度图指针是在如下方法中新增的:
Heightmap* HeightmapLoader::load() // a static method
{
// ....
Heightmap* heightmap = new Heightmap();
// ....other code
return heightmap;
}
这是否与返回在静态方法的堆栈空间中初始化的指针有关?我的删除操作正确吗?关于我可以检查什么或做得更好的其他建议吗?
I'm getting a bad error. When I call delete on an object at the top of an object hierarchy (hoping to the cause the deletion of its child objects), my progam quits and I get this:
*** glibc detected *** /home/mossen/workspace/abbot/Debug/abbot: double free or corruption (out): 0xb7ec2158 ***
followed by what looks like a memory dump of some kind. I've searched for this error and from what I gather it seems to occur when you attempt to delete memory that has already been deleted. Impossible as there's only one place in my code that attempts this delete. Here's the wacky part: it does not occur in debug mode. The code in question:
Terrain::~Terrain()
{
if (heightmap != NULL) // 'heightmap' is a Heightmap*
{
cout << "heightmap& == " << heightmap << endl;
delete heightmap;
}
}
I have commented out everything in the heightmap destructor, and still this error. When the error occurs,
heightmap& == 0xb7ec2158
is printed. In debug mode I can step through the code slowly and
heightmap& == 0x00000000
is printed, and there is no error. If I comment out the 'delete heightmap;' line, error never occurs. The destructor above is called from another destructor (separate classes, no virtual destructors or anything like that). The heightmap pointer is new'd in a method like this:
Heightmap* HeightmapLoader::load() // a static method
{
// ....
Heightmap* heightmap = new Heightmap();
// ....other code
return heightmap;
}
Could it be something to do with returning a pointer that was initialized in the stack space of a static method? Am I doing the delete correctly? Any other tips on what I could check for or do better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果从未调用
load()
会发生什么?您的类构造函数是否初始化了heightmap
,还是在到达析构函数时未初始化?另外,你说:
但是,您没有考虑到在程序执行期间您的析构函数可能会被调用多次。
What happens if
load()
is never called? Does your class constructor initialiseheightmap
, or is it uninitialised when it gets to the destructor?Also, you say:
However, you haven't taken into consideration that your destructor might be called more than once during the execution of your program.
在调试模式下,指针通常设置为 NULL,内存块清零。这就是您在调试/发布模式下遇到不同行为的原因。
我建议您使用智能指针而不是传统指针,
这样您以后就不需要删除它,因为它会自动为您完成,
另请参阅 boost::shared_ptr
In debug mode pointers are often set to NULL and memory blocks zeroed out. That is the reason why you are experiencing different behavior in debug/release mode.
I would suggest you use a smart pointer instead of a traditional pointer
that way you don't need to delete it later as it will be done for you automatically
see also boost::shared_ptr
您很可能会两次调用该 dtor;在调试模式下,指针在删除时恰好归零,在优化模式下,它保持不变。虽然这不是一个干净的解决方案,但我想到的第一个解决方法是在删除后立即设置
heightmap = NULL;
——这不是必需的,但在您寻找时肯定不会造成伤害解释为什么你要两次销毁某些 Terrain 实例!-) [[你所展示的少量代码中绝对没有任何内容可以帮助我们解释两次销毁的原因。]]It's quite possible that you're calling that dtor twice; in debug mode the pointer happens to be zeroed on delete, in optimized mode it's left alone. While not a clean resolution, the first workaround that comes to mind is setting
heightmap = NULL;
right after the delete -- it shouldn't be necessary but surely can't hurt while you're looking for the explanation of why you're destroying some Terrain instance twice!-) [[there's absolutely nothing in the tiny amount of code you're showing that can help us explain the reason for the double-destruction.]]它看起来像未初始化指针的经典案例。正如@Greg所说,如果不从 Terrain 调用 load() 会怎样?我认为您没有在
Terrain
构造函数内初始化HeightMap*
指针。在调试模式下,该指针可以设置为 NULL,并且 C++ 保证删除 NULL 指针是有效操作,因此代码不会崩溃。但是,在释放模式下,由于优化,指针未初始化,并且您尝试释放一些随机内存块,并且发生上述崩溃。It looks like the classic case of uninitialized pointer. As @Greg said, what if load() is not called from Terrain? I think you are not initializing the
HeightMap*
pointer inside theTerrain
constructor. In debug mode, this pointer may be set to NULL and C++ gurantees that deleting a NULL pointer is a valid operation and hence the code doesn't crash. However, in release mode due to optimizations, the pointer in uninitialized and you try to free some random block of memory and the above crash occurs.