调试断言失败

Posted

技术标签:

【中文标题】调试断言失败【英文标题】:Debug assertion failed 【发布时间】:2010-09-20 19:57:36 【问题描述】:

当我在调试模式下运行我的程序时,我不断遇到这个"Debug assertions failed!" 错误。我尝试在 Visual C++ 网站上查找此错误,但解释对我来说太高级了,而且它们与我对问题的最佳猜测没有任何相似之处。

我已经检查了我的代码并缩小了错误发生的范围。它似乎发生在我在计算机进入程序的下一部分之前手动删除一大堆堆数组的代码部分中。当我注释掉释放旧堆数组的部分时,程序运行得非常好。

知道这里发生了什么吗?我的编程知识还是比较基础的。

谢谢

我正在使用 Visual C++ 2008。

更多信息:

断点在此代码块处触发:

 void operator delete(
    void *pUserData
    )

    _CrtMemBlockHeader * pHead;

    RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

    if (pUserData == NULL)
        return;

    _mlock(_HEAP_LOCK);  /* block other threads */
    __TRY

        /* get a pointer to memory block header */
        pHead = pHdr(pUserData);

         /* verify block type */
        _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));//<---- break point triggers 

        _free_dbg( pUserData, pHead->nBlockUse );

    __FINALLY
        _munlock(_HEAP_LOCK);  /* release other threads */
    __END_TRY_FINALLY

    return;

此代码来自选项卡:dbgdel.cpp

我“缩小”的导致此问题的代码部分是:

delete [] topQuadanglesPositions;
delete [] fourClamps;
delete [] precaculatedClamp1;
delete [] precaculatedClamp2;
delete [] precaculatedClamp3;
delete [] precaculatedClamp4;
delete [] area;
delete [] hullConfiguration;
delete [] output;
delete [] prunedListClamp1;
delete [] prunedListClamp2;
delete [] prunedListClamp3;
delete [] prunedListClamp4;
delete [] numValidLocations;

如果我注释掉这部分,程序运行正常。

【问题讨论】:

请说得更具体一些。 “删除一堆堆数组”信息不足以知道发生了什么...... @Faken - 有争议。重新访问您的新/删除用法并替换它可能比调试您现在拥有的内容更快。也使维护工作更轻松。从您的数据中可以看出,您似乎没有破坏当前代码的风险,因为它正在破坏堆。 @Faken 对。当您到达那里时,打开 Debug->Window->Callstack(或类似的东西),然后双击出现的列表中的项目以查看您的程序如何获取此代码。 @Faken:你的代码已经被破坏了,如果让它更干净更好,你会失去什么? (还有太多的删除。) 但是由于您选择承担管理自己内存的不必要负担,您的程序已经由新/删除胶带组成,包裹着业务逻辑。撕掉胶带,留下逻辑,之后你的生活会轻松很多。特别是如果你正在学习。现在是养成良好习惯的时候了。 【参考方案1】:

您的代码正在破坏堆。第一个 sn-p 来自 C 运行时库,断言告诉您您的程序将错误的指针值传递给删除运算符。

注释掉删除语句只是隐藏了问题。当您继续开发程序时,它会以不同的方式再次困扰您。 this thread中有一些调试技巧。学习如何捕捉这些错误是任何 C 或 C++ 程序员的必经之路。欢迎加入群。

【讨论】:

感谢您的简单解释!我会浏览那个帖子,看看我是否能对正在发生的事情有任何想法。 感谢您的建议,我找到了问题所在。我将两个指针链接到同一个数组并试图删除两个指针指向的数据,这对于第一次删除很好,但第二次产生了错误。 这很快。恭喜。【参考方案2】:

断言是仅在您以调试模式运行时评估的语句(廉价调试检查)。

例如,这会在调试时断言失败,但在发布时不会导致错误:

ASSERT(1 == 2);

您调用的某些方法可能需要某个输入但没有得到它,但它不会立即导致错误(因此您的代码在非调试模式下工作。)

希望这会有所帮助。

如果您可以发布您的具体代码,有人可能会帮助您做出更具体的回复。

【讨论】:

【参考方案3】:

断言发生在程序进入非法状态时。 Assert 是程序员用代码编写的,用于在出现问题时通知他。您必须从 IDE 开始调试,并在收到断言消息时按 break。比你应该看到断言中的条件是什么,比如assert(i &gt; 1024),并确保这永远不会成为真的。也许你对 assert 的含义有一些评论,你必须找到它发生的地方和原因。

【讨论】:

以上是关于调试断言失败的主要内容,如果未能解决你的问题,请参考以下文章

调试断言失败:_CrtIsValidHeapPointer(pUserData)

调试断言失败,向量下标超出范围

c++错误:调试断言失败

调试断言失败

没有堆栈时如何调试iOS断言失败崩溃

sprintf_s() 因“调试断言失败”错误而失败