pkthapa
pkthapa

Reputation: 1071

Can we free dynamically allocation memory using realloc?

My friend and I had a discussion over freeing dynamically allocated memory. He told that a memory could be freed with realloc(), to which I denied. Let's consider the below code:

int main()
{
    int *p = (int *)malloc(sizeof(int) * 10);
    int *q = (int *)malloc(sizeof(int) * 10);

    free(p);
    p = NULL;

    realloc(q, sizeof(int) * 0);
    q = NULL;

    _getch();
    return 0;
}

Let's assume p and q are pointing to address 0x1000 & 0x2000 respectively. In the above code, p and q are int pointers pointing to dynamically allocated 40 bytes of memory blocks in the RAM. On executing free(p) frees the memory address (0x1000). The freed memory address (0x1000) could be used by an OS again. Then, NULL is assigned to pointer variable p to prevent p of becoming a dangling pointer.

realloc(q, sizeof(int) * 0);

realloc() simply shrinks the memory block pointed by q to zero. But q still points to the same address (0x2000), and that address is not freed. On assigning NULL value to pointer q, q now points to NULL and the address (0x2000) to which q was pointing is not freed and the link to that address (0x2000) is lost. That address (0x2000) cannot be used by OS in the future until the end of the program.

Is my understanding correct?

Upvotes: 0

Views: 624

Answers (2)

sjsam
sjsam

Reputation: 21965

realloc(q, sizeof(int) * 0);

is same as

realloc(q, 0);

The C standard in 7.22.3.5 ->2 The realloc function says :

..and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes.

But it doesn't explicitly specify what would happen if the new size is zero. But you still have an artist pointer that could be passed to free.

Consider

char *a;
a=malloc(2*sizeof *a);
a=realloc(a,0);
// Note I'm purposely NOT using a temporary variable to store 'realloc' results
// Moreover, above is BAD practice.
free(a); // Is this permitted? YES !! Did we technically free memory above? NO !!
//Compiler will not yell at you for the above, in fact it is legal as per the standard
return 0; // No output for this one

vs

char *a;
a=malloc(2*sizeof *a);
free(a);
//You're not suppose to free(a) again.
free(a); 
//Compiler will yell at you for the above.
return 0;

output

double free or corruption (fasttop): 0x0000000000915010

Conclusions

  • deallocation and freeing are not exactly the same things.
  • Both realloc and free can deallocate memory, but only free frees the memory.

That said

free(p);
p = NULL;

is the recommended way to free memory. Do check [ this ] answer.

Upvotes: 4

LSerni
LSerni

Reputation: 57418

realloc(, 0) is implementation dependent and not equivalent to free().

That said, you might be lucky:

#include <stdio.h>
#include <malloc.h>

int main() {
        char *a;
        a = malloc(1024);
        printf("a = %08lx\n", a);
        free(a);
        a = malloc(1024);
        printf("a = %08lx\n", a);
        realloc(a, 0);
        a = malloc(1024);
        printf("a = %08lx\n", a);
}

gcc version 6.1.1 20160815 [gcc-6-branch revision 239479] (SUSE Linux)
ldd --version

ldd (GNU libc) 2.23

a = 01dad010
a = 01dad010
a = 01dad010

So the second malloc, after realloc(, 0), "sees" a free block where before was a. I take it to mean that in this instance, realloc duplicates the behaviour of free. DO NOT RELY ON THIS.

Upvotes: 4

Related Questions