2016-10-21 2 views
0

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

int n=0,i=0; 
scanf("%d",&n); 
int *A = (int*)malloc(n*sizeof(int)); 
for (i=0;i<n;i++) 
{ 
    A[i]=2*i; 
    printf("A[%d] = %d\n",i,*(A+i)); 

} 
printf("Address of A is = %d\n",A); 
free(A); 
for (i=0;i<n;i++) 
{ 
    printf("%d\n",*(A+i)); 

} 
printf("Address of A is = %d\n",A); 

То, что я не понимаю, почему после free(A), значения А еще то же самое? Должна ли быть некоторая стоимость мусора после бесплатного? И почему адрес А остался прежним? Что на самом деле произошло после освобождения А в плане памяти?

+0

Почему бы и нет? Если вы ставите мусор в банку, он не исчезает, пока тележка не уберет его, или сосед заменит его камнями. 'free' не намеренно уничтожает освобожденную память. Это происходит, когда другому процессу присваивается одна и та же память. Также адрес 'A' остается неизменным. 'free' не может это изменить. Если вы хотите сделать недействительным, вы должны сами назначить 'A = NULL'. –

+0

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

+2

Зачем вам ожидать изменения памяти? Если вы возьмете лист бумаги с блокнота, напишите записку на нем, а затем бросьте бумагу в корзину, запись на заметке не волшебным образом исчезнет со страницы. –

ответ

3

free возвращает память в кучу. Он ничего не говорит о том, что он делает с содержимым памяти, и на самом деле обычное поведение заключается в том, что «он ничего не делает» (то есть он не выполняет чтение или запись самих данных, просто обновляет информацию отслеживания кучи, чтобы отметить эту память как доступную для повторного использования или возвращает ее в ОС).

Вы не должны полагаться на это; use-after-free - это неопределенное поведение, поэтому он может делать все, что захочет. На практике чтение больших распределений сразу после освобождения, скорее всего, будет вызвано сбоем, в то время как небольшие выделения будут продолжать работать до тех пор, пока новое malloc s не повторит использование пробела, но вы не можете положиться ни на что из этого, и это системный и шаблон использования.

Если вы обращаетесь к 0 памяти, вы делаете это неправильно, и это в конечном итоге укусит вас.

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