Я работаю с деревьями поиска, и чтобы увидеть, закончилось ли дерево, я проверяю, не является ли оно нулевым. Моя проблема в том, что когда я использую free () , значение указателя не становится NULL .

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

В этом случае я хочу удалить наибольшее число в дереве поиска, но моя функция печати не распознает освобожденное значение и печатает 0 вместо этого.

typedef struct nodo {
    int val;
    struct nodo *l, *r;
}   *ABin;

void print (ABin a) {
     if (a != NULL) {
         print (a -> l);
         printf(" %d ",a -> val);
         print (a -> r);
     }
}

ABin remBiggerA (ABin *a) {
    ABin b = (*a), aux = b;
    int i = 0;
    if (b == NULL) i = 1;
    while (i == 0) {
        if (b -> r == NULL) {
            free (b);
            i = 1;
        }
        else b = b -> r;
    }
    (*a) = aux;
    return aux;
}
1
Alexandre Rodrigues 28 Май 2017 в 04:14

2 ответа

Лучший ответ

После вызова free() для указателя он не устанавливает нулевой указатель, он делает его недействительным. Это означает, что дальнейший доступ к этому адресу указателя приводит к неопределенному поведению. Вы просто не можете получить доступ или распечатать информацию из памяти, которая уже была освобождена. Вы можете, однако, освободить указатель, а затем немедленно установить его в ноль - это совершенно правильно. Если вы уже делаете это и у вас все еще есть проблемы, то я подозреваю, что ваша проблема лежит где-то еще.

4
Hiko Haieto 28 Май 2017 в 01:25

Это ожидаемое поведение. Документацию о функции free() можно найти в Библиотека GNU C.

Освобождение блока изменяет содержимое блока. Не ожидайте найти какие-либо данные (например, указатель на следующий блок в цепочке блоков) в блоке после его освобождения.

Как уже упоминал Хико, хорошей практикой является назначение вашего указателя на NULL после вызова free().

Так,

free (b);
b = NULL;

Решит вашу проблему.


Изменить: В соответствии с рекомендациями @Seb в комментариях также проверьте Руководство по POSIX для free().

2
mercador 28 Май 2017 в 13:28