Всегда ли рекомендуется устанавливать указатели в NULL после их использования free ()?


person bodacydo    schedule 29.07.2010    source источник
comment
@bodacydo Взгляните на соответствующие вопросы в правой части страницы.   -  person    schedule 29.07.2010
comment
Спасибо Нилу и Майклу. Этот вопрос действительно отвечает на мой вопрос. После прочтения ответов у меня возник еще один вопрос - установка указателя на NULL на самом деле не скрывает ошибки? Double free () больше не обнаруживаются! Я сейчас в замешательстве, так как это действительно скрывает ошибки от обнаружения.   -  person bodacydo    schedule 29.07.2010
comment
Как же так? Освобождение указателя и установка для него значения NULL позволяет освободить память. Если вы затем решите освободить NULL, вы должны получить подтверждение или другое предупреждение. Двойное освобождение памяти отследить намного сложнее, чем освобождение NULL.   -  person Michael Dorgan    schedule 29.07.2010
comment
Но двойное освобождение в вашей программе означает, что вы написали неправильную программу. Установка указателя на NULL скрывает проблему и не решает ее.   -  person bodacydo    schedule 29.07.2010
comment
Если вы освобождаете NULL, он ничего не делает, вы не получите утверждения. Это хорошая вещь, потому что она упрощает очистку кода, вам нужно меньше if; но я, по крайней мере, могу видеть, откуда исходит OP, с точки зрения скрытых ошибок.   -  person zwol    schedule 29.07.2010
comment
@bodacydo: он скрывает двойное освобождение, но в противном случае потенциально могут быть скрыты дикие ошибки указателя (доступ к указателю после освобождения памяти). Это компромисс, поэтому не обязательно плохо (но не обязательно хорошо). Лично я не считаю, что лишнее отсутствие нулевого указателя обязательно является ошибкой, но доступ к диким указателям всегда неверен, поэтому я поддерживаю присвоение NULL.   -  person jamesdlin    schedule 29.07.2010
comment
Я считаю, что логика заключается в том, что двойное освобождение - это меньшая ошибка, которая фактически использует освобожденную память. Предполагая, что вы находитесь на машине, где разыменование NULL вызывает сигнал, вы быстро обнаружите критическую ошибку.   -  person Darron    schedule 29.07.2010
comment
Я всегда присваиваю мертвым указателям значение NULL, поскольку их адресная память больше недействительна. Мне очень нравится идея использовать значение замены, которое установлено в NULL в режиме выпуска, но что-то вроде (void*)0xdeadbeef в режиме отладки, чтобы вы могли обнаружить любое ошибочное использование.   -  person Den-Jason    schedule 02.10.2019


Ответы (4)


Плохая практика голосования у меня. Если вы действительно хотите присвоить значение, установите для него (void *) 0xdeadbeef. Однако сначала проверьте, что может делать ваш ЭЛТ. Приличный распределитель отладки установит освобожденную память в соответствии с шаблоном, который может вызвать бомбу при использовании указателя после того, как он был освобожден. Хотя это не гарантируется. Но тогда не изменение значения указателя - лучшее (и более быстрое) решение.

person Hans Passant    schedule 29.07.2010

Хотя это не может повредить, но не всегда помогает. Проблема, которую следует учитывать, заключается в том, что легко создать несколько копий указателя, и, скорее всего, вы собираетесь установить только одну из них в NULL. Классический пример того, что это совсем не помогает:

void free_graph(graph *g)
{
    ...
    free(g);
    g = NULL;  // not useful in this context
}

Проблема здесь в том, что вы устанавливаете только указатель, локальный для free_graph, в NULL, а указатель, удерживаемый вызывающим free_graph, по-прежнему будет иметь свое исходное значение.

person R Samuel Klatchko    schedule 29.07.2010

Некоторые считают это хорошей практикой, потому что это предотвращает случайный доступ к памяти после того, как она была free () ed.

person Darron    schedule 29.07.2010
comment
Прочитав ответы, я обнаружил, что это плохая практика - я скрываю ошибки двойного освобождения! Как это может быть хорошей практикой? - person bodacydo; 29.07.2010
comment
На самом деле, это не мешает вам автоматически получить к нему доступ, но вы можете (и должны) всегда проверять указатели NULL, но вы не можете определить, действителен ли указатель, отличный от NULL. Следовательно, это хорошая практика. - person cypheon; 29.07.2010
comment
Я еще не уверен, что это хорошая практика. - person bodacydo; 29.07.2010

Я думаю да ...

Когда вы закончите использовать часть menory, мы должны освободить ее (). Это позволяет использовать освобожденную память для некоторых других целей ... например, для дальнейших вызовов malloc ().

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

Надеюсь это поможет ... :)

person Flash    schedule 29.07.2010
comment
-1: Это не отвечает на вопрос. bodacydo не спрашивал, должен ли он освободить память. Он спрашивал, должен ли он установить указатели в NULL после его освобождения. - person Platinum Azure; 29.07.2010