Обнаружение неисправности неверной записи - PullRequest
0 голосов
/ 09 декабря 2011

Проблема в том, что я получаю сообщения о повреждении кучи во время удаления узлов двоичного дерева. В сообщении говорится:

HEAP [lab4.exe]: HEAP: блок 5788c0 свободной кучи, измененный на 5788e8 после была освобождена Windows запустила точку останова в lab4.exe.

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

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

Звучит так, будто я пишу в освобожденный блок памяти. Valgrind, кажется, подтверждает это сообщениями:

Неверная запись размера 4
в 0x8049C65:> BinTree :: removeTree (BinTree :: Node *) (в / net / metis / home2 / alexo2 / lab4 / a.out)
...
== 9681 == Адрес 0x402ab50 составляет 0 байтов внутри блока размером 12 free'd
в 0x40054B4: оператор delete (void *) (vg_replace_malloc.c: 346) по 0x8049C61: BinTree :: removeTree (BinTree :: Node *) (в /net/metis/home2/alexo2/lab4/a.out)
...

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

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

Итак, объект класса динамически размещается и возвращается функцией. Этот объект отслеживается с помощью указателей, пока он, наконец, не будет вставлен в узел двоичного дерева. В конце программы, когда все удаляется, вызывается деструктор:

void BinTree::makeEmpty()
{
    if ( root != NULL ) {
        removeTree( root );
    }
    root = NULL;
}

void BinTree::removeTree( Node *curr )
{
    if ( curr == NULL )
        return;

    removeTree( curr->left );
    removeTree( curr->right );

    delete curr->data;
    delete curr;

    curr->data = NULL;
    curr = NULL;
}

В некоторых функциях это вызов, который создает и возвращает динамически размещенный объект:

Item *aMovie = factory.createMovie( code.c_str() );

Только на некоторых, а не на всех узлах, когда достигается удаление curr->data, вызывается деструктор объекта, на который он указывает, затем деструктор родителя и, наконец, деструктор базового класса (все они пусты ). Иногда в родительском деструкторе, иногда в деструкторе базового класса, отображается сообщение о повреждении кучи.

Любые предложения о том, из-за чего может возникнуть проблема?

1 Ответ

1 голос
/ 09 декабря 2011

Это:

delete curr->data;
delete curr;

curr->data = NULL;
curr = NULL;

неправильно. Вы не должны писать в curr->data после того, как delete d curr. Даже не NULL.

...