我创建了一个dll,它附带了一个服务器应用程序。现在的问题是,如果我从命令提示符运行服务器,那么dll将运行正常。但是,如果我在visual studio中调试服务器,那么服务器将因dll而崩溃。然后我彻底调试了它并且在分配内存时知道它崩溃了。我检查了evry可能的事情,内存覆盖,内存泄漏,但一切似乎都很好。
之前遇到过这类问题的人。为什么会这样?我也在互联网上搜索,但我得到的只是“在发布模式下崩溃,而不是在调试模式下”。
修改
我在窗口收到以下消息:
Windows在tcas.exe中触发了断点。 这可能是由于堆的损坏,这表明tcas.exe或它已加载的任何DLL中的错误。 这也可能是由于用户在tcas.exe具有焦点时按下F12。 输出窗口可能包含更多诊断信息。
如果我点击继续,那么他们不会有任何问题。
修改
抱歉,我忘了提到它是我正在使用的调试版本而不是发布版本。
答案 0 :(得分:2)
在尝试了所有内容之后,使用所有排列组合并花费了大量时间在这上面,强有力地改变了函数的逻辑。现在它终于有效了。但是,我仍然在寻找原始问题的答案。
我还不明白的一件事是我读到了同样的问题,就像我的http://www.debuginfo.com/tips/userbpntdll.html,当我为我的应用程序启用完整的页面缓存时,如博客中所提到的,我的应用程序运行正常。它在调试时不会崩溃。我首先启用它,以便我可以获得有关堆损坏的详细信息。我希望这个博客可以帮助其他人解决类似问题。
答案 1 :(得分:0)
您的程序可能存在导致堆损坏的错误。
当您run in the debugger时,您的程序使用特殊版本的堆来帮助查找这些类型的错误。
当您从命令提示符运行时,您的程序(甚至是调试版本)在查找堆损坏方面没有获得(全部)相同的帮助。你的程序仍然有一个错误,但你只是“幸运”,你没有注意到测试运行中的任何问题。
阅读debug heap并使用它(在调试器中)查找并修复您的错误。
答案 2 :(得分:0)
如果你的代码中有指针,你最有可能使用其中一个指针访问某个未分配的内存,所以当析构函数运行时,它会崩溃你的程序。
至少这就是我遇到问题时所拥有的。
答案 3 :(得分:0)
我显然很晚才参加聚会,但我想我会分享我对这个问题的经验,试图揭开一些亮点。
我目前正在开发一个包含Windows API功能的轻量级窗口库。
我最顶层的Window类的声明包括一个指向CHAR数组基址的指针,该数组表示WNDCLASSEX类名和相应窗口的标题。此字符串在Heap上分配,并始终在Window的构造函数中复制,以避免在销毁Window对象时取消注册NULL类名。 Window的析构函数也调用CHAR缓冲区中的delete []。
当我开始实现一个独立的消息处理函数以与一个或多个Window(或派生类)实例一起使用时,首先出现了问题。循环如下:
DWORD win_api::BeginQueueingMessages
(
Window const * windowList,
UINT length,
INT showCommandIndex
)
{
BOOL processMessages = TRUE;
BOOL isFirstIteration = TRUE;
while (processMessages)
{
for (UINT i = 0; i < length; ++i)
{
Window window = windowList[i];
HWND handle = window.getHandle();
MSG message = {};
if (isFirstIteration)
{
ShowWindow(handle, showCommandIndex);
UpdateWindow(handle);
isFirstIteration = FALSE;
}
if (GetMessage(&message, handle, NULL, NULL))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
else
{
processMessages = FALSE;
}
}
}
return 0;
}
我最终确定了以下代码行作为罪魁祸首:
Window window = windowList[i];
我错误地调用了由赋值运算符触发的自动实现的复制构造函数。因此,左侧操作符的内部CHAR指针现在指向与windowList [i]的成员相同的位置,而不分配新的堆内存。
稍后,在程序终止期间,在未初始化的内存块上调用delete []并抛出C运行时异常。
我希望这会有所帮助。