How to handle realloc when it fails due to memory?

Question says it all but here is an example:

typedef struct mutable_t{
    int count, max;
    void **data;
} mutable_t;


void pushMutable(mutable_t *m, void *object)
{
    if(m->count == m->max){
        m->max *= 2;
        m->data = realloc(m->data, m->max * sizeof(void*));
    }
    // how to handle oom??
    m->data[m->count++] = object;
}

How can I handle running out of memory and not NULL out all of my data?

edit - let's assume there is something which could be done e.g. free up some memory somewhere or at least tell the user "you can't do that - you're out of memory". Ideally I would like to leave what was allocated there.


Solution 1:

The standard technique is to introduce a new variable to hold the return from realloc. You then only overwrite your input variable if it succeeds:

tmp = realloc(orig, newsize);
if (tmp == NULL)
{
    // could not realloc, but orig still valid
}
else
{
    orig = tmp;
}

Solution 2:

This is a bit of a hot button topic as there are essentially 2 schools of thought on the subject

  1. Detect the OOM, and having the function return an error code.
  2. Detect the OOM and crash your process as fast as possible

Personally I am in camp #2. Expect for very special types of applications, OOM is fatal period. True, perfectly written code can handle an OOM but so few people understand how to write code that is safe in the face of no memory. Even fewer bother to actually do it because it's almost never worth the effort.

I dislike passing the error code off to the calling function for OOM's because it is the equivalent of telling the caller "I failed and there's nothing you can do about it". Instead I prefer to crash fast so the resulting dump is as instructive as possible.