Free pointer offset no longer valid?

Viewed 362

I could have sworn this code should work, but it seems now it segfaults. Anyone know if this has always been the case or a change in glibc?


   ....
   char *tmp = malloc(50);
   tmp = &tmp[10];
   free(tmp);   // segfault
   // I thought as long as the pointer was within a valid memory block,   
   // the free was valid. Obviously I know not to double free, but this   
   // means any pointer offsets must be kept along with the original malloced 
   // pointer for the free operation.
1 Answers

This code snippet

   char *tmp = malloc(50);
   tmp = &tmp[10];
   free(tmp);   // segfault
   // I thought as long as the

is invalid because after this statement

   tmp = &tmp[10];

the pointer tmp does not have the address of the extent of the dynamically allocated memory. So the next statement

free(tmp);

invokes undefined behavior.

From the C Standard (7.22.3.3 The free function)

Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

You could write

   tmp = &tmp[10];
   //...
   free(tmp - 10 );

Or it seems what you need is to reallocate the early allocated memory like

   char *tmp = malloc(50);
   char *tmp2 = realloc( tmp, 10 );

   if ( tmp2 != NULL ) tmp = tmp2;
Related