2016-03-16 3 views
0

У меня есть некоторые проблемы с пониманием того, как работает функция free() в C. То, что делает think free(), является, как говорит название, освобождать память по адресу, который был передан в качестве аргумента. Затем я попробовал следующий код:Работа свободных() в C

#include<stdio.h> 
#include<stdlib.h> 

#include<stdio.h> 
#include<stdlib.h> 

struct node 
{ 
    int data; 
    struct node *next; 
}; 

int main() 
{ 
    struct node *first, *second, *temp; 
    first = malloc(sizeof(struct node)); 
    second = malloc(sizeof(struct node)); 
    temp = first; 
    first->data = 1; 
    first->next = second; 
    second->data = 2; 
    second->next = NULL; 
    free(first); 
    while(temp!=NULL) 
    { 
     printf("%d\n", temp->data); 
     temp = temp->next; 
    } 
    return 0; 
} 

Вышеупомянутая информация является очень простой реализацией связанного списка. Я создал два узла, а именно первый и второй, подал данные и связал их вместе. Затем я освободил первый узел и попытался напечатать связанный список. я получил следующий вывод:

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

temp = first; 

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

+2

UB и multi-dup :( –

+0

, когда вы делаете память malloc(), будет выделена из кучи для вашей программы .. как только вы освободите память, используя free(), память будет возвращена к доступному фрагменту, поэтому что другая программа может использовать эту память. Она не будет уничтожать данные, записанные в эту память, до тех пор, пока она не будет записана какой-либо другой программой. –

+0

Возможно, вас раздражает, почему temp-> данные, кажется, обнуляются, а temp-> следующий - нет. Это связано с тем, что метаданные записываются в (часть данных) выделенного фрагмента памяти на 'free()' (так называемый _free-list_) и не являются механизмом уничтожения данные на систематической основе бесплатно. – Ctx

ответ

2

Проблема с вашим предположением, что:

Если первый узел был освобожден, после чего всех данные и следующий указатель должны были быть удалены.

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

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

Это, конечно, все неопределенное поведение. Это означает, что он с радостью побежит, пока это не произойдет.

+0

Почему вы отвечаете на очень очевидный дубликат? – Magisch

+0

Вопрос не был помечен как дубликат. Я ошибся? – Wilson

+0

Если вы возьмите gander в комментариях под ним, вы увидите, что его обсуждали раньше. Вопрос в настоящее время находится на 4 закрытых голосованиях (еще 1, чтобы закрыть как обман) (хотя вы не видите этого). В таких случаях, когда несколько человек указывают, что его дубликат должен воздерживаться от ответа. – Magisch

Смежные вопросы