Sumit Naik
Sumit Naik

Reputation: 814

does realloc free the existing memory?

I am trying to reallocate memory using realloc in the below program and checking after realloc initial memory which i was reacted using malloc(i = (int*)malloc(5 * sizeof(int))) still exist or not, using below program i am able to access the data after realoc i have checked by using another pointer (i.e *m). is this proper behavior ? or memory should be free once realloc called?

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

    int main()
    {
       int *i,*jn, *m;
       i = (int*)malloc(5 * sizeof(int));
       int j,k=10;

      for(j=0 ;j<5; j++)
      {
         i[j] = j;
         printf("%d \n",i[j]);
      }

      for(j=0 ;j<5; j++)
      {
        printf("%p\n",i++);
      }

      jn = (int *)calloc(5, sizeof(*i));

      for(j=0 ;j<5; j++)
      {
         printf("%p\n",jn++);
      }

       i = i-5;
       m = i;

      printf("m = %p  %d\n",(m+1), *(m+1));

      i =(int *)realloc(i,8*sizeof(int));

      for(j=0 ;j<8; j++)
      {

         printf("%d\n",i[j]);
      }

      for(j=0 ;j<8; j++)
      {

        printf("%p\n",i++);
      }
      printf("m = %p  %d\n",(m+1), *(m+1));

      return 0;
}

Upvotes: 8

Views: 21536

Answers (2)

AnT stands with Russia
AnT stands with Russia

Reputation: 320371

Firstly, realloc might decide to

  1. Allocate a new memory block, copy data, and free the original one, or

  2. Simply expand/contract the original block "in place" without allocating the new one.

Which approach it will choose depends on the implementation and various other external factors. It might follow the first approach. Or it might follow the second approach. You can easily figure out which approach it followed by comparing the values of pointers i and m after realloc.

Secondly, if realloc decided to follow the first approach (i.e. allocate a new memory block), then the old block is indeed freed by realloc. In that case trying to access the original memory location leads to undefined behavior.

If realloc decided to follow the second approach (i.e. expand or shrink the original memory block "in place"), then m and i will keep pointing to the same location. In that case there's no surprise in seeing the same data through m.

P.S. This means that the behavior of your code is either trivial or undefined. It can't really be used to analyze whether the behavior is "proper". What did your expect to happen if the memory was indeed freed?

Upvotes: 20

Art
Art

Reputation: 20392

realloc is equivalent to:

void *
realloc(void *old, size_t newsz)
{
    size_t old_sz = internal_function_that_finds_old_size(old);
    void *new = malloc(newsz);
    if (new == NULL)
        return NULL;
    memcpy(new, old, oldsz);
    free(old);
    return new;
}

realloc can do something more efficient including not changing the pointer and just making the size allocated bigger, it can use kernel facilities to map the memory somewhere else to avoid the copy, etc. But in general realloc should be treated as doing exactly what I wrote above because that is the worst case behavior.

Now, when it comes to your program. You're touching memory through invalid pointers, anything can happen. m stops being a valid pointer after the call to realloc. It doesn't mean that anyone will stop you from using it, it just means that if you do use it your program is no longer guaranteed to do anything sensible.

Upvotes: 10

Related Questions