C中的堆错误

我知道这是非常通用的,但是当我在Visual C ++ 2008 Express中运行我的.c文件时,我得到了“this”(见下文)。 当我调用malloc ()时会发生这种情况。 我的工作 – 我正确地动态分配内存。

HEAP [Code.exe]:HEAP:免费堆块211a10在211af8被修复后被释放Windows已触发Code.exe中的断点。

这可能是由于堆的损坏,这表示Code.exe或它已加载的任何DLL中的错误。

这也可能是由于用户在Code.exe具有焦点时按下F12。

输出窗口可能包含更多诊断信息。

为什么我会收到此错误? 这甚至意味着什么?

错误消息告诉您确切的原因:

自由堆块211a10在被释放后在211af8处被修改

你有一个堆分配块被释放然后写入内存区域。 写入释放的内存块并不好。

调用malloc时,实际上并没有发生错误; 就在它触发免费堆扫描时。 实际的错误发生在某个地方之前。 你在地址211a10上摩托了一些内存(这就是malloc给你的回复)。 然后你(或其他一些lib)释放了它。 然后,当你在调试模式下调用malloc时,它会扫描整个堆 – 这是对你这个可怜的程序员的礼貌。 它发现有人(你或你调用的一些lib)写入了该数组的一部分,特别是在地址211af8或0xe8字节的数组中。 所以你要么仍然挂在一个已被释放(最有可能)并使用它的指针上,要么你只是在捣乱随机存储器。

在我的情况下,有类似的症状,问题是结构对齐不匹配(/ Zp选项)

我为我的代码定义了一个与外部库(wxWidgets)不同的结构对齐方式。 但是,wxWidgets是使用makefile构建的,所以它是使用defaut / Zp编译的。 并且wxWidget是静态链接的。

您可以这样做,但如果您尝试从代码中删除wxWidgets类对象编译器会对结构成员的确切大小感到困惑。 在运行时,您收到以下消息:

 HEAP[Code.exe]: HEAP: Free Heap block 211a10 modified at 211af8 after it was freed Windows has triggered a breakpoint in Code.exe. 

解:

  • 确保在所有代码和库中使用相同的“Struct Member Alignment”。

  • 最好的规则是定义/ ZP使用“默认”值。 在Visual Studio中,在“属性C / C ++代码生成”下

  • MSDN引用:“ 除非您有特定的对齐要求,否则不应使用此选项。 ” 请参阅此处

  • 提示:如果需要控制某些结构中的对齐, 请使用#pragma pack

例:

 #pragma pack(1) // - 1 byte alignment typedef union { u64 i; struct{ // CUSTOMS.s is used by Folders u32 uidx; // Id, as registered byte isoS, isoT; // isoS/isoT combination. byte udd0, udd1; // custom values (TBD) }s; }CUSTOMS; struct Header // exactly 128 bits { u32 version; u32 stamp; // creation time CUSTOMS customs; // properties } #pragma pack() // this pragma restores the **default** alignment 

*

希望这个解释有所帮助,因为这实际上不是代码中的错误,而是严重的配置错误:难以检测,因为它位于微妙的编译器选项中。 谢谢大家,

    *

我正确地动态分配内存。

我认为这里的问题是你没有正确地分配内存。 我的意思是,你可能会尝试使用释放的内存。 对不起,我不能再帮忙了,你可以添加实际的代码。

我的工作 – 我正确地动态分配内存。

但是你确定你的缓冲区大小都正确吗?你可以正确地free()它们吗? 双重释放和缓冲区溢出很容易导致堆损坏,这可能导致malloc()以各种方式失败。

如果malloc()内部使用的管理结构损坏,通常不会立即导致错误。 但后来调用malloc()free()试图使用这些受损的结构将失败做不稳定的事情。

你在数组上使用malloc()吗? 因为我认为错误可能是你忘记在最后分配一个额外的内存位置 – 会发生什么呢?它会尝试写入那个未分配给它的位置,并假设它正在尝试写入一个地方已经被释放了。