程序仅在调试器外部的发布模式下崩溃

Mat*_*ský 9 c++ memory crash heap

我有相当大的程序(> 10k行的C++代码).从Visual Studio中启动时,它在调试模式或发布模式下都能正常工作,但是从命令行手动启动时,释放模式二进制文件通常会崩溃(并不总是!!!).

删除行会导致崩溃:

bool Save(const short* data, unsigned int width, unsigned int height, 
          const wstring* implicit_path, const wstring* name = NULL, 
          bool enable_overlay = false)
{
    char* buf = new char[17];
    delete [] buf;
}
Run Code Online (Sandbox Code Playgroud)

编辑:根据请求扩展了示例.

在我的测试用例中,"len"长度为16.没关系,如果我对buf做了一些事情,它会在删除时崩溃.

编辑:应用程序工作正常没有删除[]行,但我想它会泄漏内存(因为块永远不会被分配).删除行后从未使用的buf.它似乎也不会与除char之外的任何其他类型崩溃.现在我真的很困惑.

崩溃消息非常不明确(典型的Windows"xyz.exe已停止工作").当我单击"调试程序"选项时,它进入VS,其中错误被指定为"访问冲突写入位置xxxxxxxx".虽然"没有为任何堆栈帧加载符号",但无法找到错误的位置.

我想这是一个非常严重的堆损坏的情况,但如何调试这个?我应该寻找什么?

感谢帮助.

Eri*_*ric 11

你有没有检查其他地方的内存泄漏?

通常奇怪的删除行为是由于堆在某一点上被破坏引起的,然后很久以后,由于另一个堆的使用而变得明显.

调试和发布之间的区别可能是由Windows在每个上下文中分配堆的方式引起的.例如,在调试中,堆可能非常稀疏,并且损坏不会立即影响任何内容.

  • @rogerdpack二进制搜索.删除/禁用代码的解析并逐渐归入有罪行. (2认同)

Mat*_*lia 5

在调试器中启动并自行启动之间的最大区别是,当从调试器中启动应用程序时,Windows提供了一个"调试堆",它填充了0xBAADF00D模式; 请注意,这不是CRT提供的调试堆,而是填充了0xCD模式(IIRC).

是微软为此功能提供的少数几个提及之一,在这里您可以找到一些关于它的链接.

该链接中还提到"启动程序并使用调试器附加到程序中不会导致它使用"特殊调试堆"."