C中的堆错误

时间:2010-01-26 03:02:33

标签: c heap-memory

我知道这很普遍,但是当我在Visual C ++ 2008 Express中运行.c文件时,我得到“this”(见下文)。当我拨打malloc ()时会发生这种情况。接受我的工作 - 我正确地动态分配内存。

  

HEAP [Code.exe]:HEAP:自由堆块211a10在211af8被释放后被修改   Windows已在Code.exe中触发了断点。

     

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

     

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

     

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

为什么会出现此错误?这甚至意味着什么?

6 个答案:

答案 0 :(得分:4)

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

  

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

就我而言,出现类似症状的问题是结构对齐不匹配(/ 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.

解决方案:

  • 请务必在所有代码和库中使用相同的“结构成员对齐”。

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

  • MSDN引用:“ 除非您有特定的对齐要求,否则不应使用此选项。 See here

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

示例:

#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

*

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

    *

答案 3 :(得分:1)

  

我正确地动态分配内存。

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

答案 4 :(得分:0)

  

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

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

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

答案 5 :(得分:0)

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