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); ... }