1

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.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 4
    `free` *has* freed the memory. But it doesn't magically cease to exist. It just hasn't yet been re-used by another process, or function. And there are not 3 pointers, just 1. – Weather Vane Jun 17 '16 at 19:03
  • If the memory is really free()-d how does p[3] retain it's original value? I agree it is undefined behavior and hence it should give arbitary values, right? – Stephen Stemmer Jun 17 '16 at 19:24
  • @StephenStemmer define arbitrary. – Sourav Ghosh Jun 17 '16 at 19:28
  • @StephenStemmer `free`ing memory makes it available for re-use, that's all. That does not give it "arbitrary values". It's just available for re-use, and whatever values are written to it *then* will be to all intents arbitrary as far as your continued use is concerned. Some or all of it might have been reallocated within `printf`. But it's useless to speculate. – Weather Vane Jun 17 '16 at 19:38
  • hehe, it does have an arbitrary value. How would you know if it's *unarbitrary?* – DigitalRoss Jun 17 '16 at 19:56
  • @DigitalRoss well yes, but my point was that when you `free` memory it is not "given" an arbitrary value. OP should know that it is *undefined behaviour* to access freed memory, that's all. – Weather Vane Jun 17 '16 at 20:30
  • Yeah, that was for Stephen. Those @OP tags are redundant, as the OP is automatically notified. – DigitalRoss Jun 17 '16 at 21:28
  • @StephenStemmer, why would you expect values in free()d memory to change? wouldn't it be a total waste of time? If I hand you a glass of water and say "this is yours now", do you automatically dump it on the floor or fill it with something else? "Free" just means "doesn't belong you anymore". It doesn't mean there's any reason for it to change. – Lee Daniel Crocker Jun 17 '16 at 22:45

1 Answers1

6

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.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261