Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What if malloc fails?

Tags:

c

memory

malloc

If a malloc allocation fails, should we try it again?

In something like this:

char* mystrdup(const char *s)  
{
    char *ab = NULL;

    while(ab == NULL) {
        ab=(char*)malloc(strlen(s)+1);  
    }

    strcpy(ab, s);
    return ab;
}

Is the while loop valid for checking the memory allocation?

like image 751
sam32 Avatar asked Aug 03 '12 03:08

sam32


People also ask

What happens when malloc fails to allocate memory?

The behavior is undefined, but most likely you'll get a negative result. Remember that the type of an expression in C is determined by the expression itself, not by the context in which it's evaluated.

Do you need to free a failed malloc?

Consider a case where function A() constructs a linked-list and in each iteration it calls to another function, B() . Now, if a malloc failure occured at B() , it must free() the memory it allocated but function A() should do that as well.

Does malloc ever fail?

But yes, malloc can fail on Linux. You're correct in the way that it's default behavior, but the behavior can be turned off. Also, if you're using cgroups (or anything that leverages that like containers) you can put a limit on the memory resource and then malloc will fail.

What does the malloc () function return if the function fails to allocate memory a 0 B void pointer C a null pointer D NULL?

The malloc() function takes a single parameter, which is the size of the requested memory area in bytes. It returns a pointer to the allocated memory. If the allocation fails, it returns NULL.


5 Answers

In general, a modern malloc() implementation will return NULL only as an absolute last resort, and trying again will definitely not help. The only thing that will help is freeing some memory and then trying again. If your application holds any expendable resources, this would be the time to free them, and then give it another shot.

In some environments, a useful practice is to allocate a small amount of memory as a rainy-day fund. If malloc() ever does return NULL, you can free that rainy-day fund, and then allocate whatever resources you need to be able to handle the error and exit gracefully. This was a common practice when programming with the old Macintosh Toolbox; if malloc() returned NULL, you could use that space to create a dialog to report the problem before exiting.

like image 65
Ernest Friedman-Hill Avatar answered Oct 17 '22 09:10

Ernest Friedman-Hill


In a single-threaded program "trying again" without freeing any memory between tries make no practical sense. It will just loop forever.

In a multi-threaded program this might "work", if another thread running in parallel suddenly decides to free some of its own memory. The loop in such case would constitute a classic "busy waiting" loop. But even in this case such code has very little practical value for more reasons than one.

like image 32
AnT Avatar answered Oct 17 '22 08:10

AnT


No, never. If malloc returns NULL, that indicates an error, and you should probably abort.

like image 23
Richard J. Ross III Avatar answered Oct 17 '22 09:10

Richard J. Ross III


Without arguing why or when this would be useful, attempts to reallocate in a loop could work, at least on Windows with 64 bit code, and default pagefile settings. Moreover, this could buy surprisingly more additional virtual memory. Although, do not do this in an infinite loop, but instead use a finite number of retries. As a proof, try the following code that simulates leaking 1 Mb of memory. You have to run it in Release build, preferably not under debugger.

for (int i = 0; i < 10; i++)
{
  size_t allocated = 0;
  while (1)
  {
    void* p = malloc(1024 * 1024);
    if (!p)
      break;

    allocated += 1;
  }

  //This prints only after malloc had failed.
  std::cout << "Allocated: " << allocated << " Mb\n";
  //Sleep(1000);
}

On my machine with 8 Gb of RAM and system managed pagefile, I get the following output (built with VS2013 for x64 target, tested on Windows 7 Pro):

Allocated: 14075 Mb
Allocated: 16 Mb
Allocated: 2392 Mb
Allocated: 3 Mb
Allocated: 2791 Mb
Allocated: 16 Mb
Allocated: 3172 Mb
Allocated: 16 Mb
Allocated: 3651 Mb
Allocated: 15 Mb

I don't know exact reason of such behavior, but it seems allocations start failing once the pagefile resizing cannot keep up with requests. On my machine, pagefile grew from 8 gb to 20 Gb after this loop (drops back to 8 Gb after the program quits).

like image 21
0kcats Avatar answered Oct 17 '22 08:10

0kcats


It is incredibly unlikely that this will do what you want; if you're out of memory, busy-looping until you get more is likely to be disappointing. You should just return the NULL to the calling program so that it can deal with resource exhaustion, either by releasing memory it no longer needs or by returning an error.

like image 38
tbert Avatar answered Oct 17 '22 08:10

tbert