Function realloc() is broken - Not
Pascal Cuoq - 9th Feb 2012This 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);
...
}
