Why does not free() deallocate all allocated memor

2019-03-01 14:26发布

问题:

This question already has an answer here:

  • free() not deallocating memory? 5 answers

I don't know if I am doing something wrong or if my concept is somewhat wrong

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

int main()
{
     int *p;
     p=calloc(3,sizeof(int));
     p[0]=10;
     p[1]=15;
     p[2]=30;
     printf("\n%d\n%p\n%d\n%p\n%d\n%p\n\n",p[0],p,p[1],p+1,p[2],p+2);
     free(p);
     //p=NULL;
     printf("\n%d\n%p\n%d\n%p\n%d\n%p\n\n",p[0],p,p[1],p+1,p[2],p+2);
     return 0;
}

When the 2nd, printf() is run, it shows p[2]=30, whereas p[0]=p[1]=0 (in gcc ubuntu and some arbitary values in Code::Blocks windows). I have 2 questions.

  1. Why free() frees first 2 pointers and not the 3rd. one?
  2. Why are the values shown 0 in ubuntu when it seems right to show arbitary values?

I am a beginner so please bear with me. I have tried the same thing with malloc(), and same thing happens.

回答1:

Using memory that has already been free()-d invokes undefined behavior. Don't do that.

Quoting C11, annex §J.2, Undefined behavior

The value of a pointer that refers to space deallocated by a call to the free or realloc function is used.

To elaborate, calling free() on a pointer does not set the pointer to NULL or anything else. It just marks the memory as re-usable by the memory manager. That memory location (pointer) is not valid anymore for the program, so you should not be using it.

As a preventive measure to the above problem, it's considered a good coding practice to set the pointer to NULL explicitly after calling free(). However, FWIW, this is not mandatory.

Quoting C11, chapter 7.22.3.3

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. [...]

Also, just to add, partial free() is not possible by calling free(), anyway. You can refer to this previous answer for clarification.