处理破坏堆的对象
在我的应用程序中,我正在创建一个非常像这样的对象:
connect() {
mVHTGlove = new vhtGlove(params);
}
一旦我要关闭应用程序,我就调用这个对象:
disconnect() {
if (mVHTGlove)
delete mVHTGlove;
}
此调用总是触发一个断点,并显示以下消息:
Windows 已触发断点 DesignerDynD.exe。
这可能是由于 堆,这表明存在错误 DesignerDynD.exe 或它的任何 DLL 已加载。
这也可能是由于用户 DesignerDynD.exe 时按 F12 有焦点。
输出窗口可能有更多 诊断信息。
我无法修改 vhtGlove 类来修复堆栈的损坏,因为它是仅以头文件、lib 文件和 dll 形式提供的外部库。
有什么方法可以干净地使用这个类吗?
**** 编辑 ::: 我试图将内容精简到最低限度,但是我得到了相同的结果......这里有整个代码。
#include "vhandtk/vhtCyberGlove.h"
#include "vhandtk/vhtIOConn.h"
#include "vhandtk/vhtBaseException.h"
using namespace std;
int main(int argc, char* argv[])
{
vhtCyberGlove* testGlove = NULL;
vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
try
{
testGlove = new vhtCyberGlove(&gloveAddress,false);
if (testGlove->connect())
cout << "Glove connected successfully" << endl;
else
{
throw vhtBaseException("testGlove()->connect() returned false.");
}
if (testGlove->disconnect())
{
cout << "Glove disconnected successfully" << endl;
}
else
{
throw vhtBaseException("testGlove()->disconnect() returned false.");
}
}
catch (vhtBaseException *e)
{
cout << "Error with gloves: " << e << endl;
system("pause");
exit(0);
}
delete testGlove;
return 0;
}
删除手套时仍然崩溃。
编辑 #2 :: 如果我只是分配和删除 vhtCyberGlove 的实例,它也会崩溃。
int main(int argc, char* argv[])
{
vhtCyberGlove* testGlove = NULL;
vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
testGlove = new vhtCyberGlove(&gloveAddress,false);
delete testGlove; //<<crash!
return 0;
}
有任何想法吗?
谢谢!
杰成
In my application I am creating an object pretty much like this :
connect() {
mVHTGlove = new vhtGlove(params);
}
and once I am about to close application I call this one :
disconnect() {
if (mVHTGlove)
delete mVHTGlove;
}
This call always triggers a breakpoint with the following message :
Windows has triggered a breakpoint in
DesignerDynD.exe.This may be due to a corruption of the
heap, which indicates a bug in
DesignerDynD.exe or any of the DLLs it
has loaded.This may also be due to the user
pressing F12 while DesignerDynD.exe
has focus.The output window may have more
diagnostic information.
I cannot modify the vhtGlove class to fix the corruption of the stack as it is an external library provided only in the form of header files, lib files and dlls.
Is there any way to use this class in a clean way ?
**** EDIT ::: I tried to strip things down to a bare minimum, however I get the same results... here you have the ENTIRE code.
#include "vhandtk/vhtCyberGlove.h"
#include "vhandtk/vhtIOConn.h"
#include "vhandtk/vhtBaseException.h"
using namespace std;
int main(int argc, char* argv[])
{
vhtCyberGlove* testGlove = NULL;
vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
try
{
testGlove = new vhtCyberGlove(&gloveAddress,false);
if (testGlove->connect())
cout << "Glove connected successfully" << endl;
else
{
throw vhtBaseException("testGlove()->connect() returned false.");
}
if (testGlove->disconnect())
{
cout << "Glove disconnected successfully" << endl;
}
else
{
throw vhtBaseException("testGlove()->disconnect() returned false.");
}
}
catch (vhtBaseException *e)
{
cout << "Error with gloves: " << e << endl;
system("pause");
exit(0);
}
delete testGlove;
return 0;
}
Still crashes on deletion of the glove.
EDIT #2 :: If I just allocate and delete an instance of vhtCyberGlove it also crashes.
int main(int argc, char* argv[])
{
vhtCyberGlove* testGlove = NULL;
vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
testGlove = new vhtCyberGlove(&gloveAddress,false);
delete testGlove; //<<crash!
return 0;
}
Any ideas?
thanks!
JC
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一种可能是 mVHTGlove 没有被初始化为 0。如果在没有调用 connect 的情况下调用了detach,那么您将尝试释放垃圾指针。 繁荣。
另一种可能性是,您实际上在该点之前损坏了堆栈,但这就是损坏实际上导致崩溃的地方。 检查这一点的一个好方法是注释掉尽可能多的代码,并且仍然让程序运行,然后看看是否仍然出现损坏。 如果没有,请慢慢地恢复一些代码,直到看到它恢复为止。
一些进一步的想法(在您编辑之后)。
您可能会检查 API 是否没有自己的内存管理调用,而不是期望您手动“新建”和“删除”对象。 我这么说的原因是,当一些内存在 DLL 内部管理而另一些内存在外部管理时,我发现一些 DLL 存在看起来很像这样的问题。
One possiblity is that mVHTGlove isn't being initialized to 0. If disconnect was then called without a connect ever being called, then you'd be attempting to deallocate a garbage pointer. Boom.
Another possibility is that you are actually corrupting the stack a bit before that point, but that is where the corruption actually causes the crash. A good way to check that would be to comment out as much code as you can and still get the program to run, then see if you still get the corruption. If you don't, slowly bring back in bits of code until you see it come back.
Some further thoughts (after your edits).
You might check and see if the API doesn't have its own calls for memory management, rather than expecting you to "new" and "delete" objects manually. The reason I say this is that I've seen some DLLs have issues that looked a lot like this when some memory was managed inside the DLL and some outside.
删除
vhtGlove
时报堆损坏错误。 然而,也可能是您自己的代码导致了损坏。 这通常是由于覆盖堆上分配的缓冲区而发生的,可能是由于调用malloc
。 或者您可能两次删除同一个对象。 您可以通过使用像 std::auto_ptr 这样的智能指针来存储指向对象的指针来避免这种情况。The heap corruption error is reported when the
vhtGlove
is deleted. However, it may just as well be your own code that causes the corruption. This often happens as a result of overwriting a buffer allocated on the heap, perhaps from a call tomalloc
. Or you are perhaps deleting the same object twice. You can avoid this by using a smart pointer likestd::auto_ptr
to store the pointer to the object.您可能尝试追踪损坏源的一件事是,当检测到堆损坏时,使用 Visual Sudio 的“内存”窗口查看 mVHTGlove 指向的内存位置。 看看您是否在该内存中看到任何看起来明显像是超出缓冲区的内容。 例如,如果您看到程序中其他地方使用了一个字符串,那么就去查看操作该字符串的代码——它可能会超出其缓冲区。
One thing you might try to track down the source of the corruption is to look at the memory location pointed to by
mVHTGlove
using Visual Sudio's "Memory" window when the heap corruption is detected. See if you see anything in that memory that looks obviously like something that overran a buffer. For example, if you see a string used elsewhere in the program, then go review the code that manipulates that string -- it might be overrunning its buffer.鉴于 vhtCyberGlove 的实现位于另一个 DLL 上,我将查找堆不匹配的情况。 例如,在 VS 中,如果 DLL 链接到发布 CRT,而 EXE 链接到调试 CRT,就会发生这种情况。 在这种情况下,每个模块都使用不同的堆,一旦您尝试使用错误的堆释放内存,就会崩溃。
在您的情况下,vhtCyberGlove 可能会获取在其他 DLL 上分配的一些内容,但是当您删除 vhtCyberGlove 实例时,这些内容将被直接删除,即引用您的堆而不是 DLL 的。 当试图释放指向另一个堆的指针时,你实际上会破坏你的堆。
如果确实如此,在没有更多细节的情况下,我可以提供两个修复:
Given vhtCyberGlove's implementation is on another DLL, I would look for heaps mismatch. In VS, for example, this would happen if the DLL is linked to the Release CRT, while your EXE is linked to the Debug CRT. When this is the case, each module uses a different heap, and as soon as you try to free memory using the wrong heap, you'll crash.
In your case, it is possible that vhtCyberGlove gets some stuff that is allocated on the other DLL, but when you delete the vhtCyberGlove instance the stuff is being deleted directly, namely referring to your heap rather than the DLL's. And when trying to free a pointer that points to another heap, your effectively corrupting yours.
If this is indeed the case, without having more details I can offer two fixes:
您将本地 vhtIOConn 的地址传递给构造函数。 该对象是否有可能取得该指针的所有权并尝试在析构函数中删除它?
You are passing the address of a local vhtIOConn to the constructor. Is it possible that the object is assuming ownership of this pointer and trying to delete it in the destructor?