Function realloc() is broken - Not

Pascal Cuoq - 9th Feb 2012

This post is a sequel of this post, in which I argued that it is not possible to double-free a piece of memory, only to pass indeterminate data (specifically, a dangling pointer) to a function (specifically, free()).

Broken

This time I am arguing that the standardized function realloc() is broken. By this I do not mean that a particular implementation is broken. This happens, as I found out searching the web for these very words, just before starting on this post. I mean that the standard definition is broken: it forces the programmer to write eir program either in such a way that it may manipulate indeterminate data (specifically, a dangling pointer) or in such a way that it may leak memory (specifically, the block that couldn't be enlarged).

Naively using realloc(): memory leak

char *p = malloc(...);
...
p = realloc(p, ...);
if (p)
{
  /* good: we got the additional
     memory we need. */
  ...
}
else
{
  /* We didn't get the memory. Ah well... 
  We didn't need it that badly anyway,
  let's continue. */
  ...
}

The problem with this program is that it leaks memory. In the else branch, the block has been preciously kept in memory by realloc(), but the variable p has been overwritten with NULL, the result of the realloc() call, so that there is no way to access it any more or, for that matter, to free it.

The idiomatic solution

The above is a standard pitfall of realloc(), and there is an idiomatic solution:

char *p = malloc(...);
...
char *old = p;
p = realloc(p, ...);
if (p)
{
  /* good: we got the additional
     memory we need. */
  ...
}
else
{
  /* We didn't get the memory. Ah well... 
  We didn't need it that badly anyway.
  In fact, let's throw away the block right now! */
  free(old);
  ...
}
Pascal Cuoq
9th Feb 2012