When to check the return value of malloc

M

Marty James

Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

OTOH, if you're allocating a gigabyte for a large array, this might
fail, so you should definitely check for a NULL return.

So somewhere in between these extremes, there must be a point where you
stop ignoring malloc's return value, and start checking it.

Where do people draw this line? I guess it depends on the likely system
the program will be deployed on, but are there any good rule-of-thumbs?

Rgds,
MJ
 
D

Default User

Marty said:
Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

No, always check.
OTOH, if you're allocating a gigabyte for a large array, this might
fail, so you should definitely check for a NULL return.

No, always check.
So somewhere in between these extremes, there must be a point where
you stop ignoring malloc's return value, and start checking it.

No, always check.
Where do people draw this line?

Always check.
I guess it depends on the likely
system the program will be deployed on, but are there any good
rule-of-thumbs?

Sure, always check.




Brian
 
F

fnegroni

I *always* check malloc.
Why drawing a line? Optimisation?
It's damn too specific a reason to even talk about "drawing a line".
Do you draw other lines? like "at which point does a memory leak
really is bad"? or "when is a segmentation fault really that annoying
for the user?"

Sorry for the sarcasm but I think he primary role of the computer
programmer is to be in control.
 
R

Randy Howard

Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.
Why?

OTOH, if you're allocating a gigabyte for a large array, this might
fail, so you should definitely check for a NULL return.

Why can one fail, but not the other? I think you are making claims
based upon your perception of the statistical likelihood of a malloc
failure for a given size.
So somewhere in between these extremes, there must be a point where you
stop ignoring malloc's return value, and start checking it.

Or you just check it all the time and not pretend that you know more
about the malloc internal implementation than you actually do.
Where do people draw this line? I guess it depends on the likely system
the program will be deployed on, but are there any good rule-of-thumbs?

I'd be very leery of any code where the line was drawn anywhere other
than "in all cases we check malloc return values".
 
I

Ian Collins

Marty said:
Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.
Ever heard of the final straw? Any call to malloc can fail.
 
K

Kaz Kylheku

Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

Okay, that's our base case. so what is the inductive hypothesis?
It is this: if we don't have to check about checking some N byte
malloc, surely, we don't have to care about a malloc of N + 1 bytes.
What's one byte? It often takes three just to make alignment.

So, by induction, we don't ever have to check the return value of
malloc.
 
P

Paul Hsieh

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

The only sane circumstance not to check the output of malloc for NULL
is if you yourself have supplied the implementation for malloc. And
even then, you need to have a very good, well defined way of
guaranteeing a usable and non-NULL return (or exit() or throw() on
failure.) In any event, doing this is not standards compliant (its
not portable to other systems which might inline calls to malloc, or
refuse to link to redefinitions of malloc).

The standards specified malloc() basically requires that you always
check the return because it may fail for *any* reason. About the only
time you could possibly get away with not checking is if you have to
know an awful lot about your system and then only accept a finite
fixed amount of malloc()s right when the system starts. (Like on the
old Mac OS which didn't support multitasking and checked for the
predeclared amount of memory to be available before the application
even started running. Even on DOS systems you really can't be totally
sure.)

There is also absolutely no real benefit to *not* checking for the
success or failure of malloc(). The fastest generally usable malloc()
implementations I've seen are at least 50 machine cycles, whereas the
overhead of checking for NULL can't be more than a cycle or two.
 
E

Eric Sosman

Marty said:
Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

"Obviously," you can allocate an infinite amount of
memory as long as you get it in 20-byte chunks? Did you
used to work for Enron or something?
 
K

Kaz Kylheku

check the return because it may fail for *any* reason.  About the only
time you could possibly get away with not checking is if you have to
know an awful lot about your system and then only accept a finite
fixed amount of malloc()s right when the system starts.

Or you know that your system overcommits virtual memory, so that
malloc keeps ``working'' even though your total allocations have
already exceeded core + swap.
 
K

Keith Thompson

Paul Hsieh said:
The standards specified malloc() basically requires that you always
check the return because it may fail for *any* reason. [...]

There is also absolutely no real benefit to *not* checking for the
success or failure of malloc().
[...]

I agree completely.

There is one "unreal" benefit: simplicity. The tricky part is
figuring out what the heck to do if malloc() fails.

There's an old saying: Never check for an error condition you don't
know how to handle.

But if you can't figure out what to do, you can always just terminate
the program. It's not necessarily the best thing you can do, but it's
the second simplest, and it's almost certainly better than the
simplest (ignoring the error).
 
J

jacob navia

Keith said:
Paul Hsieh said:
The standards specified malloc() basically requires that you always
check the return because it may fail for *any* reason. [...]
There is also absolutely no real benefit to *not* checking for the
success or failure of malloc().
[...]

I agree completely.

There is one "unreal" benefit: simplicity. The tricky part is
figuring out what the heck to do if malloc() fails.

There's an old saying: Never check for an error condition you don't
know how to handle.

But if you can't figure out what to do, you can always just terminate
the program. It's not necessarily the best thing you can do, but it's
the second simplest, and it's almost certainly better than the
simplest (ignoring the error).

No, in many situations you should return an error.

Simple isn't it?

The part of the program fails because of lack of memory,
and then you call:

MessageBox("Document is too big to be loaded");

and nothing serious happens.

A malloc failure is not ALWAYS fatal!
 
I

Ian Collins

jacob said:
Keith said:
Paul Hsieh said:
The standards specified malloc() basically requires that you always
check the return because it may fail for *any* reason. [...]
There is also absolutely no real benefit to *not* checking for the
success or failure of malloc().
[...]

I agree completely.

There is one "unreal" benefit: simplicity. The tricky part is
figuring out what the heck to do if malloc() fails.

There's an old saying: Never check for an error condition you don't
know how to handle.

But if you can't figure out what to do, you can always just terminate
the program. It's not necessarily the best thing you can do, but it's
the second simplest, and it's almost certainly better than the
simplest (ignoring the error).

No, in many situations you should return an error.
How does that contradict what Keith said?
 
R

Randy Howard

Keith said:
Paul Hsieh said:
The standards specified malloc() basically requires that you always
check the return because it may fail for *any* reason. [...]
There is also absolutely no real benefit to *not* checking for the
success or failure of malloc().
[...]

I agree completely.

There is one "unreal" benefit: simplicity. The tricky part is
figuring out what the heck to do if malloc() fails.

There's an old saying: Never check for an error condition you don't
know how to handle.

But if you can't figure out what to do, you can always just terminate
the program. It's not necessarily the best thing you can do, but it's
the second simplest, and it's almost certainly better than the
simplest (ignoring the error).

No, in many situations you should return an error.

Simple isn't it?

The part of the program fails because of lack of memory,
and then you call:

MessageBox("Document is too big to be loaded");

and nothing serious happens.

Or it might not appear, because there isn't enough memory to put it on
screen. Or it might not appear for a couple days, while thrashing
through swap.
A malloc failure is not ALWAYS fatal!

No, it isn't. Not handling them at all usually has disastrous results
though.
 
R

Randy Howard

"Obviously," you can allocate an infinite amount of
memory as long as you get it in 20-byte chunks? Did you
used to work for Enron or something?

This thread was useful, now I know I never have to buy extra memory
again.
 
M

Mark McIntyre

Marty said:
Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

Er, no...
OTOH, if you're allocating a gigabyte for a large array, this might
fail, so you should definitely check for a NULL return.
Mhm.

So somewhere in between these extremes, there must be a point where you
stop ignoring malloc's return value, and start checking it.

The point at which your programme moves from being a trivial proof of
concept or quick hack, into being a real programme with some form of
worth to you, your customers or your colleagues.

IOW, _always_ check malloc in real programmes.
 
J

jameskuyper

Marty said:
Howdy,

I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a filename or
something, there's no point putting in a check on the return value of
malloc.

That's complete nonsense which will probably get you fired some day,
as many others have already explained.
Where do people draw this line? I guess it depends on the likely system
the program will be deployed on, but are there any good rule-of-thumbs?

The only time I ever fail to check the return value from malloc() is
if I change my mind about using the return value before I get around
to checking it:

a = malloc(sizeof(*a));
b = malloc(sizeof(*b)*num_b);
c = malloc(offsetof(c,flex_array)+num_c*sizeof(c->flex_array[0]);

if(a==NULL || b==NULL || c==NULL)
{
// error handling
}
else
{
// code using a, b, and c
}
free(a);
free(b);
free(c);

As you can see, the above code never bothers checking whether c is
null, if it turns out that either a or b is null.
 
J

jameskuyper

(e-mail address removed) wrote:
....
c = malloc(offsetof(c,flex_array)+num_c*sizeof(c->flex_array[0]);

That obvious wasn't actually compiled:

c = malloc(offsetof(flex_struct, flex_array)+num_c*sizeof(c-
flex_array[0]));

with appropriate definitions implied for c and flex_struct.
 
R

Richard Tobin

Where do people draw this line? I guess it depends on the likely system
the program will be deployed on, but are there any good rule-of-thumbs?

You're obviously a troll, but let's try to find some situations where
it would be ok to ignore malloc()'s return value. Then you can decide
whether you're in one of them.

Obviously if it doesn't matter that your program occasionally fails in
an obscure way or produces the wrong answer, then it's ok.

If your program will always be run on a system where dereferencing the
null pointer (and relevant offsets from it) produces an error, and you
don't mind getting "segmentation fault" instead of a more useful error
message, then it's ok.

And in these two cases, since it's true that small allocations will
fail less often than large ones, you can indeed weigh the
inconvenience against the likelihood of failure for a given size.

Also, if your program doesn't use so much memory that it could run out
of address space, and will always be run on a system where malloc()
never returns NULL for memory exhaustion (e.g. systems with overcommit
turned on), checking won't make any difference.

-- Richard
 
K

Keith Thompson

jacob navia said:
Keith said:
Paul Hsieh said:
The standards specified malloc() basically requires that you always
check the return because it may fail for *any* reason. [...]
There is also absolutely no real benefit to *not* checking for the
success or failure of malloc().
[...]

I agree completely.

There is one "unreal" benefit: simplicity. The tricky part is
figuring out what the heck to do if malloc() fails.

There's an old saying: Never check for an error condition you don't
know how to handle.

But if you can't figure out what to do, you can always just terminate
the program. It's not necessarily the best thing you can do, but it's
the second simplest, and it's almost certainly better than the
simplest (ignoring the error).

No, in many situations you should return an error.

Simple isn't it?

The part of the program fails because of lack of memory,
and then you call:

MessageBox("Document is too big to be loaded");

and nothing serious happens.

A malloc failure is not ALWAYS fatal!

jacob, I would agree with everything you wrote above, and it would be
entirely consistent with what I wrote, if you merely changed the word
"No" to "Yes" (or "Yes, and ").
 
C

CBFalconer

Marty said:
I was reflecting recently on malloc.

Obviously, for tiny allocations like 20 bytes to strcpy a
filename or something, there's no point putting in a check on
the return value of malloc.

Oh? Try the following:

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

#define SZ 40

int main(void) {
unsigned long count;
void *ptr;

count = 0;
while (ptr = malloc(SZ)) count++;
printf("Failed after %lu tries\n", count);
return 0;
}

(It may take a while - just increase SZ)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top