The return of malloc

Should you always check the return value of malloc? There’s a heated debate over the answer.

One group insists that, in good software development, you always check the return value of a function, including malloc. It appears that most software developers are in this group.

The other group thinks otherwise. I’m in this group. Here’s why.

I was taught, like many programmers, to always check the return value of malloc. This thread made me think otherwise: Always check malloc’ed memory? The asker raises many interesting points.

When thinking about checking the return value of malloc, it’s important to consider the operating system, hardware, and type of software that you are working on. Linux may behave differently from FreeBSD, a desktop computer may behave differently from a mobile phone, and a GUI application may need different considerations than a shared library. Also remember that it may not even be your application that is causing malloc to fail.

I’m primarily concerned with the case of a GUI application running on Linux on a desktop computer, because that’s what I work on. Even so, it’ll be fun to think of the other cases.

Failure Response

So, let’s say you check the return value every time you use malloc. What do you when a return from malloc fails? You could simply quit your application immediately. You could try to quit your application gracefully. You could cancel the command that caused the fail and display an error message. You could loop until either malloc returned a valid result or the computer catches on fire.

Can You Respond?

Let’s pretend that malloc failed. Imaging the state that the computer is in that caused it to fail. Would it still be able to do any processing at all? I agree that it is extremely important for an application to never lose the user’s data, but would the computer even still be able to recover anything at that point?

Does malloc Fail?

In Linux, malloc may never even fail. On the malloc man page under “Bugs”, it states that just because malloc didn’t fail doesn’t mean it has enough memory.

The Trial

So, I wrote some code to try and make malloc fail. When it does, it tries to recover and quit gracefully.

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct NODE
{
  int data[40000000];
  struct NODE* next;
} NODE;

int
main(void)
{
  NODE* node;
  NODE* first;
  NODE* last;
  int stop;
  int count;

  first = NULL;
  stop = 0;
  count = 0;

  while (!stop) {

    node = (NODE*)malloc(sizeof(NODE));
    count++;

    if (node == NULL) {
      printf("FAILED! %d \n", count);
      stop = 1;
    } else {
      if (first == NULL) {
        first = node;
        last = node;
      } else {
        last->next = node;
        last = last->next;
      }
    }
  }

  count = 0;
  node = first;

  while (node != NULL) {
    last = node;
    node = node->next;
    free(last);
    count++;
  }

  printf("FREED %d \n", count);

  exit(0);
}

The Results

Here are the results when running it on three different operating systems.

Arch Linux: After 55 seconds, the message “Killed” was displayed. This was a message from the operating system, not my code. My program never had the opportunity to see a failure from malloc nor try to cleanup after it.

Haiku: Almost immediately the program stopped. The output was “FAILED 10, FREED 9″. That means that after trying to allocate about half a gigabyte of memory, it failed to allocate anymore and was able to clean up the stuff it had.

Windows XP: The results were similar to Haiku: Almost immediately the program stopped. The output was “FAILED 12, FREED 11″.

Conclusion

By using this simple test, it appears that checking the result of malloc can be a worthwhile task. My conclusion is contrary to my feelings from the beginning of this post. I think I just might have to change my programming habits.

Comments are closed.