1

我创建了一个 dll,它与一个服务器应用程序相连。现在的问题是,如果我从命令提示符运行服务器,那么 dll 将运行良好。但是如果我在visual studio中调试服务器,那么服务器会因为dll而崩溃。然后我彻底调试了它,并知道它在分配内存时崩溃了。我检查了所有可能的事情,内存覆盖,内存泄漏,但一切似乎都很好。

任何人以前都遇到过这种类型的问题。为什么会这样?我也在互联网上搜索过,但我得到的只是“在发布模式下崩溃而不是在调试模式下”。

编辑:

我在窗口上收到以下消息:

Windows 已在 tcas.exe 中触发断点。这可能是由于堆损坏,这表明 tcas.exe 或其已加载的任何 DLL 中存在错误。这也可能是由于用户在 tcas.exe 具有焦点时按 F12。输出窗口可能有更多诊断信息。

如果我点击继续,那么他们不会有任何问题。

编辑:

抱歉,我忘了提到这是我正在使用的调试版本,而不是发布版本。

4

4 回答 4

3

在尝试了一切,使用了所有的排列组合并在这上面花费了大量时间之后,我有力地改变了函数的逻辑。现在它终于开始工作了。但是,我仍在寻找我原来问题的答案。

我也不明白的一件事是我读到了和我一样的问题,在这里http://www.debuginfo.com/tips/userbpntdll.html当我为我的应用程序启用完整的页面堆时,正如在博客,我的应用程序运行良好。调试时不会崩溃。我首先启用了它,以便我可以获得有关堆损坏的详细信息。我希望这个博客能帮助其他有类似问题的人。

于 2013-05-16T09:37:47.987 回答
0

您的程序可能存在导致堆损坏的错误。

当您在调试器中运行时,您的程序会使用一个特殊版本的堆来帮助查找这些类型的错误。

当您从命令提示符运行时,您的程序(甚至是调试版本)在查找堆损坏方面并没有(全部)获得相同的帮助。您的程序仍然存在错误,但您只是“幸运”地发现在测试运行中没有发现任何问题。

阅读调试堆并使用它(在调试器中)来查找和修复您的错误。

于 2013-05-10T16:24:36.047 回答
0

如果您的代码中有指针,您很可能正在使用其中一个指针访问某个未分配的内存,因此当析构函数运行时,它会使您的程序崩溃。

至少当问题相同时,我就是这样。

于 2013-05-10T18:44:33.393 回答
0

我显然很晚才参加聚会,但我想我会分享我在这个问题上的经验,以试图阐明一些观点。

我目前正在开发一个包装 Windows API 功能的轻量级窗口库。

我最顶层的 Window 类的声明包括一个指向 CHAR 数组基地址的指针,该数组表示 WNDCLASSEX 类名和相应窗口的标题。此字符串在堆上分配,并始终在 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 运行时异常。

我希望这有帮助。

于 2016-06-23T23:30:31.767 回答