OmriJ
OmriJ

Reputation: 81

Creating a function to check if malloc succeeded

So I am doing a small project which involves using the malloc, realloc and calloc functions from time to time. I understood that after every allocation I should be checking if it failed and it points to null like so:

int* arr = malloc(size*sizeof(int));

if (!arr)
{
      printf("ERROR! Not enough memory!\n");
      exit(1); // to exit the program immedietly.
}

and I was wondering if it is okay to create a method that will do just that for every kind of pointer like so:

void checkOutOfMemory(const void* p) //gets a pointer and exit program if points to null.
{
    if (!p)
    {
        printf("ERROR! Out of memory!\n");
        exit(1);
    }
}

I mean, it works so far, but I started wondering if there are any special cases I didn't know about.

Upvotes: 7

Views: 1821

Answers (3)

user2736738
user2736738

Reputation: 30916

Everything is all right but just do one thing instead of printing message get the benefit of fact that malloc sets errno (Not from standard rather from Open group based spec). So do this

if(!p)
  perror("malloc failed");
  exit(EXIT_FAILURE);    
}

perror do this - appends a message generated from strerror(errno) to the string you are printing.(Giving you a plausible reason for the failure of malloc).

Also there is one thing that you must remember when you do this

void *p = malloc(SOMESIZE);

check whether SOMESIZE == 0 because malloc may return NULL when you pass 0 to it. Handle that case separately. In case you get SIZE!=0 and get NULL in p throw error.

Also malloc's parameter type is unsigned check if that criteria is being satisfied before calling my_malloc.

The code will be something like,

void * my_malloc(size_t SIZE){
  void *p = malloc(SIZE);
  if(p == NULL && SIZE){
     perror("malloc failed");
     exit(EXIT_FAILURE);    
  }
  return p;
}

Note: The setting errno in malloc failure is specified in Open Group Based Spec (alk mentioned it).

Upvotes: 4

dbush
dbush

Reputation: 223699

This is a good way to perform this kind of check. It prevents the error checking code from being duplicated in numerous places. You should however use perror which will include a textual description of why malloc failed.

You could go one step further and perform the allocation and check at once:

void *safe_malloc(size_t size)
{
    void *ptr = malloc(size);

    if (!ptr && (size > 0)) {
      perror("malloc failed!");
      exit(EXIT_FAILURE);
    }

    return ptr;
}

Since malloc can return NULL on success if the given size is 0, you need to check for that as well.

You can then create similar functions for realloc and calloc.

Upvotes: 14

You can code your malloc like wrapper which check against failure, as answered by dbush.

Actually, such a function is conventionally called xmalloc and provided by many (free software) libraries, notably GNU libiberty. See this.

However, some systems have memory overcommitment; this is a feature that I dislike (it makes malloc never fail, even when your virtual address space is exhausted).

Upvotes: 2

Related Questions