Does realloc free the former buffer if it fails?

No, it does not. That aspect has often annoyed me since you can’t just use:

if ((buff = realloc (buff, newsize)) == NULL)
    return;

in your code if you want to free the original on failure. Instead you have to do something like:

if ((newbuff = realloc (buff, newsize)) == NULL) {
    free (buff);
    return;
}
buff = newbuff;

Of course, I understand the rationale behind keeping the original buffer intact on failure but my use case has popped up enough that I generally code my own functions to handle that case, something like:

// Attempt re-allocation. If fail, free old buffer, return NULL.

static void *reallocFreeOnFail (void *oldbuff, size_t sz) {
    void *newbuff = realloc (oldbuff, sz);
    if (newbuff == NULL) free (oldbuff);
    return newbuff;
}

// Attempt re-allocation. If fail, return original buffer.
// Variable ok is set true/false based on success of re-allocation.

static void *reallocLeaveOnFail (void *oldbuff, size_t sz, int *ok) {
    void *newbuff = realloc (oldbuff, sz);
    if (newbuff == NULL) {
        *ok = 0;
        return oldbuff;
    }

    *ok = 1;
    return newbuff;
}

The relevant section in the C11 standard states (my italics):

7.20.3.4 The realloc function

If ptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by the
calloc, malloc, or realloc function, or if the space has been deallocated by a call
to the free or realloc function, the behavior is undefined. If memory for the new
object cannot be allocated, the old object is not deallocated and its value is unchanged.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)