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