Ошибка кучи в C - PullRequest
       18

Ошибка кучи в C

2 голосов
/ 26 января 2010

Я знаю, что это действительно общее, но я получаю «это» (см. Ниже), когда запускаю свой файл .c в Visual C ++ 2008 Express. Это происходит, когда я звоню malloc (). Возьми мою работу над этим - я динамически распределяю память правильно.

HEAP [Code.exe]: HEAP: блок свободной кучи 211a10 изменен на 211af8 после его освобождения Windows запустила точку останова в Code.exe.

Это может быть связано с повреждением кучи, что указывает на ошибку в Code.exe или любой из загруженных им библиотек DLL.

Это также может быть связано с тем, что пользователь нажимает клавишу F12, когда Code.exe находится в фокусе.

В окне вывода может быть больше диагностической информации.

Почему я получаю эту ошибку? Что это вообще значит?

Ответы [ 6 ]

4 голосов
/ 26 января 2010

Ошибка на самом деле не происходит при вызове malloc; это только когда он запускает бесплатное сканирование кучи. Фактическая ошибка произошла где-то раньше. Вы выделили немного памяти по адресу 211a10 (именно это вам и передал malloc). Тогда вы (или какая-то другая библиотека) освободили ее. Затем, когда вы вызываете malloc в режиме отладки, он сканирует всю кучу - как любезность вам, плохой программист. Он обнаруживает, что кто-то (вашу или какую-то библиотеку, которую вы называете) записал поверх этого массива, особенно по адресу 211af8, или 0xe8 байтов. Таким образом, вы либо все еще держите указатель, который был освобожден (скорее всего) и используете его, или вы просто уничтожаете случайную память.

4 голосов
/ 26 января 2010

Сообщение об ошибке сообщает вам, почему вы его получили:

Свободный блок кучи 211a10, измененный на 211af8 после освобождения

У вас был выделенный блок кучи, который был освобожден, а затем что-то записано в эту область памяти. Нехорошо писать в освобожденный блок памяти.

2 голосов
/ 21 января 2013

В моем случае, с похожими симптомами, проблема заключалась в несоответствии выравнивания структуры (опция / Zp)

Я определил для своего кода другое выравнивание структуры, чем внешние библиотеки (wxWidgets). Однако wxWidgets был собран с make-файлом, поэтому он был скомпилирован с использованием 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» во всем коде и библиотеках.

  • Лучшим правилом является определение / ZP для использования значения по умолчанию. В Visual Studio в разделе Свойства C / C ++ Генерация кода

  • MSDN cite: " Вы не должны использовать эту опцию, если у вас нет особых требований к выравниванию. " Смотрите здесь

  • Совет: используйте # pragma pack , если вам нужно контролировать выравнивание в некоторых структурах Смотрите там

* +1039 * Пример:
#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

*

Надеюсь, это объяснение поможет, потому что на самом деле это не ошибка в коде, а серьезная ошибка конфигурации: ее трудно обнаружить, поскольку она находится в тонких настройках компилятора. Спасибо за все,

1 голос
/ 26 января 2010

Я динамически распределяю память правильно.

Я думаю, что проблема в том, что вы распределяете память неправильно. Я имею в виду, что вы можете пытаться использовать свободную память. Извините, я не могу помочь, вы могли бы добавить код.

0 голосов
/ 26 января 2010

Используете ли вы malloc () для массива? Поскольку я думаю , ошибка может просто заключаться в том, что вы забыли выделить дополнительную область памяти в конце - что происходит, если она пытается записать в эту область, которая не выделена для и предполагает, что пытается написать в место, которое уже было освобождено.

0 голосов
/ 26 января 2010

Возьми мою работу над этим - я динамически распределяю память правильно.

Но вы уверены, что все ваши буферы имеют правильный размер, и вы free() правильно их используете? Двойное освобождение и переполнение буфера могут легко привести к повреждению кучи, что может привести к сбою malloc() всеми способами.

Если структуры управления, используемые внутри malloc(), будут повреждены, это обычно не приведет к ошибке сразу. Но более поздние вызовы malloc() или free(), которые пытаются использовать эти поврежденные структуры, потерпят неудачу.

...