3

So I know that realloc() can follow 2 ways. The first way is allocating memory in a new address and freeing old memory. Second way is allocating memory in the same address so that you will only need to free that address. So in both ways, you only have to free the address that realloc() allocates. But, what would happen if realloc() returned NULL, do I have to free old memory like this? :

//so in the first way, as b would be another address, a would be freed and if b is NULL it is no necessary to free it. But, if it follows second way, b will be same address as a and if it is NULL, I need to free old memory (a), right? 
int *a = (int*)malloc(sizeof(int));
int *b = (int*)realloc(a,sizeof(int)*3);

if(!b){
   free(a);
}
Steve Friedl
  • 3,929
  • 1
  • 23
  • 30
Elrisas
  • 49
  • 5
  • 1
    Short answer: yes. The man page on Linux indicates: “ If realloc() fails the original block is left untouched; it is not freed or moved.” Someone more versed with standards can probably find the Posix or C99 reference or similar. – Max Jun 24 '22 at 20:41
  • 2
    The C standard [§7..22.3.5 The `realloc` function](https://port70.net/~nsz/c/c11/n1570.html#7.22.3.5) specifies the behaviour: _If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged._ – Jonathan Leffler Jun 24 '22 at 20:45

1 Answers1

4

If in this code snippet

int *a = (int*)malloc(sizeof(int));
int *b = (int*)realloc(a,sizeof(int)*3);

the function realloc will return NULL then in this case the early allocated memory will not be freed.

So how the program or the function should behave in this case depends on the context. You can free the previously allocated memory

free( a );

or continue to deal with the previously allocated memory taking into account that realloc failed.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • So making this would be a bad practice because we will lose old memory, right? -> "int *a = (int*)malloc(sizeof(int)); a = (int*)realloc(a,sizeof(int)*3);" – Elrisas Jun 24 '22 at 20:49
  • 1
    Correct. Always realloc using a temporary pointer. That way when (not if) `realloc` fails, you don't overwrite your original pointer address with `NULL` creating a memory leak. – David C. Rankin Jun 24 '22 at 20:52
  • @Vlad from Moscow , I have one question, if realloc follows second way, if you free (a) and the adress of a is the same as b, aren´t you making double free if you later decide to free(b)? Also if you free a, the reallocated memory could not be dereferenced if the realloc follows second way.. Is this right? – Elrisas Jun 24 '22 at 20:54
  • 1
    If `realloc` succeeds, the memory pointed to by `a` is freed by `realloc` after the contents of the original block is copied to the new reallocated block now pointed to by `b`. It's only in the case `realloc` fails do you need to free `a` when you are done with it. (and why you can't do `a = realloc (a, newsize);` safely) – David C. Rankin Jun 24 '22 at 20:58
  • 2
    @Elrisas What is the second way? If the memory was not reallocated then only the pointer a has a valid value and to free it you should write free( a ); If the memory was successfully reallocated then usually it is written a = b; and the pointer b plays the role of an intermediate pointer. Otherwise you need to free memory using only the value stored in the pointer b. – Vlad from Moscow Jun 24 '22 at 20:58