Clarification regarding malloc and free in C

Seth442's Avatar, Join Date: Feb 2010
Newbie Member
Suppose I were to write the following code:

int *p = malloc(sizeof(int) * 10);
int *q;
q = p + 1;
free(q);

Will calling free with argument q free up the entire block of "size" 10? Or will it only free up the 2nd through 10th spots?

Is there any circumstance in which memory that has been allocated using malloc is freed without explicitly calling free?

Thank you!
Gene Poole's Avatar, Join Date: Nov 2009
Contributor
Since you are calling free on a pointer that was NOT allocated by malloc, the behavior is undefined.
Seth442's Avatar, Join Date: Feb 2010
Newbie Member
Oh ok, I thought the important thing was that the argument of free pointed to memory that had been malloc'ed. I did not realize that the argument itself had to have been initialized with malloc.

What about the following code:

int *makePointer (VOID)
{
int *p = malloc(sizeof(int) * 10);
return p;
}

int main ()
{
int *ptr;
ptr = makePointer();
}

Can I call free with the argument ptr in main? If I cannot, then how do I free up the memory?

And what if I wrote the following:

int *p = malloc(sizeof(int) * 10);
int *q = malloc(sizeof(int) * 9);
p = q;
free(p);

Is the malloced memory of size 10 freed? Or of size 9? Or is the behavior undefined?

What if I had a pointer p that had been initialized with malloc and then I assigned it to point to a different address, but did not save the original address. Does that mean I can no longer free the memory?

What if I had a pointer p that had been initialized with malloc , I stored the address in a variable x, then I assigned p to point somewhere else, then I reassigned p to point to the address stored in x. Then can I call free with argument p to free up that memory?

Does anyone know where I can read an in depth explanation of some of these details? It is really bugging me.
Gene Poole's Avatar, Join Date: Nov 2009
Contributor
Typically the memory manager keeps track of malloc'ed memory by storing the pointer in a table and when free or realloc, etc. are called, it looks up the pointer in its table so the the value of the actual pointer is the lookup key. So, with respect to the first part of your post, yes, you can free the pointer returned by the function since its value is the same.

In the second case, you are reassigning your pointer to a different location and therefore the memory allocated by p is left dangling with no way to free it.
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
> Can I call free with the argument ptr in main?

Yes.

> And what if I wrote the following...?

You would have a memory leak because you would have no way of freeing the memory at p.

> Does that mean I can no longer free the memory?

Yes. The memory would remain allocated and this is a memory leak.

> What if ...(complicated stuff I couldn't be bothered to decipher)

If you allocate memory, you MUST MUST MUST MUST keep the pointer given you by malloc. It doesn't matter where you keep it, you can keep it in p, copy it to x, write it to disk, punch it to paper tape, burn it onto the moon with a laser, anything you like, as long as when you're done with the memory you can retrieve the pointer and pass it to free. Then the memory will be correctly deallocated. It will NOT be correctly deallocated if you do not follow this very simple rule.

ptr=malloc(n) -> Keep the value in ptr.

free(ptr) -> ptr here must be the value returned by malloc.
rekha_sri's Avatar, Join Date: Feb 2010
Light Poster
When you want to call the free function,you should use the argument as
which is returned by the previous call of the malloc.Otherwise it would display the error like invalid pointer in free(). If you already called the free(), again tried to call the free() with same pointer variable behavior is undefined.
sganesh's Avatar, Join Date: Feb 2010
Light Poster
int *p=(int *)malloc(12);
free(p);

Your question is whether calling free function with argument p will clear the remaining elements.

It won't Because free will clear the first location which is pointed by p. If you want to clear all locations that is allocated by malloc. you need to use loop you need to have the temporary pointer then freeing it then move to the next pointer.
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Quote:
Originally Posted by sganesh View Post
int *p=(int *)malloc(12);
free(p);

Your question is whether calling free function with argument p will clear the remaining elements.

It won't Because free will clear the first location which is pointed by p. If you want to clear all locations that is allocated by malloc. you need to use loop you need to have the temporary pointer then freeing it then move to the next pointer.
You need to work on your knowledge of Free and Malloc. This is completely not true.
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Absolutely. free(p) will free the 12 bytes that were allocated by malloc(12). sganesh, wherever you got that idea from, it's complete nonsense.

Now if you do
Code:
int **p=malloc(12*sizeof(int*));
for (int i=0; i<12; i++)
  p[i]=malloc(12*sizeof(int));
(which creates a 2D array of 144 ints), THEN you will need a loop to free each of p[i] before you free p itself. Observe then that the malloc's exactly match the free's (there will be 13 of each). Every malloc must be matched by *exactly* one free for the application not to exhibit undefined behaviour.
sganesh's Avatar, Join Date: Feb 2010
Light Poster
Quote:
Originally Posted by shabbir View Post
You need to work on your knowledge of Free and Malloc. This is completely not true.
can you tell me which is not true.

I am coming to say pointer is like an array. If you free one location it is not mean that other locations also cleared.