2017-01-27 15 views
-2

Значит ли значение указателя становится NULL после его освобождения?C - указатель не null после освобождения

int* p = malloc(sizeof(*p)); 

free(p); 

if(p==NULL) 
    printf("Null\n"); 
else 
    printf("Not null\n"); 

Выход:

Not null 

Ну, я предполагаю, что нет;

Во всяком случае, я задал вопрос ранее сегодня:

Посмотрите здесь: C - How can I free dynamically allocated memory?

List* head1 = NULL; 

insertFront(&head1, 1); 
insertFront(&head1, 2); 

print(head1); 

while (head1) 
{ 

    List *temp = head1; 
    head1 = head1->next; 
    free(temp); 
} 

if(head1 == NULL) 
    printf("Null\n"); 
else 
    printf("Not null\n"); 

Выход в этом случае:

Null 

В этом случае после освобождения head1 (узлы также) head1 становится нулевым, не так ли?

И, наконец, я пропустил некоторые понятия?

head1 - null, однако p нет.

Мой вопрос:

Почему значения отличается от Head1 и р?

+2

Свободная функция не может и не может обнулить указатель. Чтобы он мог это сделать, вам нужно передать указатель на переменную указателя. – PSkocik

+0

@PSkocik спасибо, но как насчет значения head1? –

+1

в целом, сделайте это хорошей привычкой, после 'free'ing вверх указателя ** всегда ** установите его в' NULL' после этого, как если бы вы когда-либо сняли ссылку с указателя 'NULL', это приведет к сбою намека на то, что произошло. – t0mm13b

ответ

2

Состояние петли

while (head1) 
     ^^^^^^ 
{ 

    List *temp = head1; 
    head1 = head1->next; 
    free(temp); 
} 

становится равным false, когда элемент данных next следующего узла равен NULL

head1 = head1->next; 
^^^^^   ^^^^^ 

Это не имеет ничего общего с функцией free. Функция принимает аргумент по значению. То есть он имеет дело с копией оригинала [указатель. Поэтому исходный указатель сам по себе не будет изменен.

+0

Это замечательно! Теперь я получил это! На самом деле эта голова обманывается, переходя связанный список, а не освобождая его. –

+1

@Sumon Вы правы. :) –

5

Освобождение указателя не меняет его значения.

Вам необходимо вручную установить его на NULL после освобождения его, если это то, что вы хотите.

+0

Даже попытка прочитать/скопировать указатель после освобождения - это UB. – chux

+0

См. Мой конкретный вопрос, который я включил после редактирования. –

1

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

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

Установка на NULL не является автоматической операцией после освобождения.

3

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

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

Причина, по которой head1 равна NULL в конце цикла, заключается в том, что вы изменяете значение head1 внутри цикла, чтобы перейти по списку, пока оно не достигнет конца. Мы знаем, что мы находимся в конце списка, когда находим значение NULL в указателе next. Поэтому в конце цикла head1 - NULL.

+0

спасибо, у меня есть это. –

0

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

Это так вопрос содержит дополнительную информацию: What is the difference between freeing the pointer and assigning it to NULL?