If malloc fails

H

Harti Brandt

On Mon, 19 Jul 2004, H.A. Sujith wrote:

HS>If malloc fails what should I do?
HS>
HS>1. Exit imediately.
HS>2. Print an error message (or put a log entry) and exit.
HS>3. Print an error message (or put a log entry) and continue
HS>execution (after possibly recovering from the error).

That depends stronlgy on the concrete application. For one-shot programs
like 'ls' or so a malloc() failure is most probable a problem in the
environment and just printing a message (if possible) and exiting is the
best one can do. For programs that are long running or run under special
conditions (think of controlling software for a nuclear power plant) this
is not an option and they probably have to try to recover (and log, of
course).

HS>Printing an error message might be difficult in a graphical environment.

That's one of the reasons why such programs sometimes simply disappear
from the screen without any hint what happend.

harti
 
S

Stefan Ram

H.A. Sujith said:
If malloc fails what should I do?
1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

If there would be a single correct answer, it might have
already become part of this library call.

The answer is: It depends on the application.
Printing an error message might be difficult in a graphical
environment.

One solution is to use an "env" object:

if( !malloc( size ))
{ env->failure( "malloc failed." ); }

The variable "env" might have file scope or the object might
be passed to every function.

"failure" is a function member of a structure object, which
points to a function used to log and/or display messages in an
application specific manner.

For a graphical environment it might be redefined without
the need to change any functions using the "env" to
display messages.
 
B

brian

H.A. Sujith said:
If malloc fails what should I do?

1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Printing an error message might be difficult in a graphical environment.

I have gone down the avenue of trying to make malloc() fail, and it's
easier said then done. Also, implementation specific settings have to
be set to create a possibility of malloc() failing. (e.g., RLIMIT_DATA
in linux, malloc.conf in BSD, etc.).

A good exercise would be just trying to get malloc() to fail under your
implementation to make sure the above items you listed even work. And
do not forget to allocate enough space for the trailing '\0'.

I have recently moved over to openBSD to experiment with making malloc()
fail. It's really implementation specific, so I'm curious what the
regulars here think about porting malloc() between platforms since there
doesn't seem to be a standard as to whether or not errno is set when
malloc() fails.

brian
 
D

Darrell Grainger

If malloc fails what should I do?

1. Exit imediately.
Maybe.

2. Print an error message (or put a log entry) and exit.
Maybe.

3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Maybe.

The answer all depends on the situation. If IO absolutely must have a
successful malloc or there is not point continuing then I would exit. If
I'm attempt to allocate a large block of memory but can get by with a
smaller block then adjust and keep going.

Do I print an error message? Depends on the environment. If the program is
going to be used in an automated or embedded system then I would not print
an error message (there will be no human to see it). If the application is
always going to be run interactively then I would print an error message.
Printing an error message might be difficult in a graphical environment.

Why? If it is just because you have to go through the effort of creating a
dialog then learn to create a dialog. If it is because a failed malloc
means there isn't enough memory to display an error dialog, see if there
is a system level way of printing an error message. Often the OS will
reserve memory for printing critical error dialogs. If your OS does not do
this, allocate enough memory right at the start so there is memory to
print an error dialog. Keep that memory in reserve until you quit the
application.
 
K

Kenneth Brody

H.A. Sujith said:
If malloc fails what should I do?

1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).
[...]

It depends entirely on the situation.

For example, I have a report generator program which allocates memory (in
chunks) for sorting the selected records. If malloc fails after I have
already allocated at least one memory block, then it doesn't matter, and
I simply stop trying to allocate more memory, and use only the memory
that I already have. In this case, the answer is:

4. Continue running, but without the memory you tried to allocate.

Of course, if the first malloc fails, then it's a fatal error.
 
H

H.A. Sujith

If malloc fails what should I do?

1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Printing an error message might be difficult in a graphical environment.
 
E

Emmanuel Delahaye

H.A. Sujith a formulé la demande :
If malloc fails what should I do?

1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Printing an error message might be difficult in a graphical environment.

There is no definitive answer, and it's beyond the C-language itself.
It's more a specification and eventually design issue.

-> At some library level, I tend to return some information that a
problem occured (null pointer, error value etc.)

-> At application level, I tend to display some message (to stderr,
stdout, some log file, a message box in graphical environment, ...).
The exit is an option if the error is not recoverable. You could simply
retry later, or with a smaller amout if it doesn't hurt.

But to conclude, and to come back to the C-language, a pointer with a
null value must not be dereferenced.
 
M

Malcolm

H.A. Sujith said:
If malloc fails what should I do?

1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Printing an error message might be difficult in a graphical environment.
It depends what you are allocating. If you are allocating a few bytes, maybe
for a filename, on a large system then basically malloc() cannot fail. The
system will have issued "low on memory" warnings long before this happens.
However for the program to be correct, you still need to handle the failure.
Exit is perfectly reasonable.
However if you are allocating a very large data set, it is entirely possible
that the computer is genuinely out of memory. So you need to tell the user
what has happened, and allow him to close other applications and retry, or
do whatever else is necessary to recover.
 
M

Mark McIntyre

If malloc fails what should I do?

Whatever is most appropriate for your application.
1. Exit imediately.
2. Print an error message (or put a log entry) and exit.

neither very suitable for pacemakers, air traffic control systems etc.....
typically more ok for simple tools eg cat, cp.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

may not be possible, but graceful cleanup is advisable.
Printing an error message might be difficult in a graphical environment.

There's usually a system-specific way to flag fatal errors which uses
reserved system memory and is thus not subject to your own malloc woe.
 
C

Christian Bau

"H.A. Sujith said:
If malloc fails what should I do?

1. Exit imediately.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Printing an error message might be difficult in a graphical environment.

You look at it from the programmer's point of view. You should look at
it from the user's point of view. What are the consequences for the user
of your software of your action? What can you do or what do you have to
do to improve these consequences?

If I spent twelve hours editing a document, choose "Save" from a menu,
and the program runs out of memory just at this point and exits (after
printing an error message or not) without saving twelve hours of my
work, then the programmer responsible deserves to be shot.
 
K

Keith Thompson

If you're in a graphical environment, presumably you have some way of
displaying a message, perhaps by popping up a dialog window.
It depends what you are allocating. If you are allocating a few bytes, maybe
for a filename, on a large system then basically malloc() cannot fail. The
system will have issued "low on memory" warnings long before this happens.

You're assuming that malloc() will fail only if the entire system is
running low on memory. Many systems place limits on the memory
allocated by a single program; a program can hit those limits long
before the system as a whole is in trouble.

Even if the entire system is running low on memory, it's unlikely that
a given program will be aware of any "low on memory" warnings that the
system might have generated. If the system has 10 bytes left to
allocate, and a program asks for 20, the allocation will fail.
Obviously a large request is more likely to fail than a small one, but
it's always possible that a 1-byte request will be the straw that
breaks the camel's back.

As for recovery strategies, it's seldom sensible for a program to try
to continue whatever task it was working on after a malloc() failure.
Whether aborting the task means aborting the entire program depends on
the nature of the program.

If the program has built up a lot of valuable information, it should
try to save it before aborting. (For example, if a text editor
doesn't have enough memory to insert another character into the
buffer, it shouldn't bail out and throw away the whole buffer.)

There is no universal answer.
 
R

roman ziak

Christian Bau said:
You look at it from the programmer's point of view. You should look at
it from the user's point of view. What are the consequences for the user
of your software of your action? What can you do or what do you have to
do to improve these consequences?

If I spent twelve hours editing a document, choose "Save" from a menu,
and the program runs out of memory just at this point and exits (after
printing an error message or not) without saving twelve hours of my
work, then the programmer responsible deserves to be shot.

Totally agree.

If there is a chance somebody wasted a lot of time with the program,
exit() is not an option.
 
G

Gordon Burditt

Printing an error message might be difficult in a graphical environment.
If you're in a graphical environment, presumably you have some way of
displaying a message, perhaps by popping up a dialog window.

The error-retentive approach to this is that if you run out of
memory trying to create a dialog window, you MUST report it by
trying to create a dialog window. When that fails, you must report
that also. Similarly, you MUST report all failures to write a
message on stderr with an error message on stderr, thereby ensuring
that if the disk ever fills up, it will STAY filled up.

What is the return value from malloc() that constitutes a "low memory"
warning?

Gordon L. Burditt
 
A

Arto Huusko

brian said:
there
doesn't seem to be a standard as to whether or not errno is set when
malloc() fails.

SUSv3 has this to say:

---
RETURN VALUE

Upon successful completion with size not equal to 0, malloc() shall
return a pointer to the allocated space. If size is 0, either a null
pointer or a unique pointer that can be successfully passed to free()
shall be returned. Otherwise, it shall return a null pointer [CX]
and set errno to indicate the error.
 
M

Malcolm

Gordon Burditt said:
What is the return value from malloc() that constitutes a "low memory"
warning?
We're talking about allocating a few bytes, maybe for a file name, on a
system with many megabytes available.
For malloc() to fail in these circumstances the pool of memory available to
the program must be extremely low. Now a decent OS will not allow this to
happen in the absence of warning. For instance the system may start running
very slowly because of excessive use of swap space, or there may be warning
messages sent to the user. Only if the user fails to respond to these
symptoms will malloc() actually fail.
So handling the failure is a formality only, and there is not much point
uglifying code for an error condition which will never be encountered. So an
abort is reasonable. In fact the most likely cause of failure is probably a
programming error causing a garbage value to be passed to malloc() (if
strlen doesn't have a prototype in scope and size_t isn't an unsigned int,
for example). Once a program is incorrect, there's very little you can do.

However if you are allocating a large amount of memory, then it is likely
that malloc() may fail, so the above doesn't apply.
 
K

Keith Thompson

Malcolm said:
We're talking about allocating a few bytes, maybe for a file name, on a
system with many megabytes available.
For malloc() to fail in these circumstances the pool of memory available to
the program must be extremely low. Now a decent OS will not allow this to
happen in the absence of warning. For instance the system may start running
very slowly because of excessive use of swap space, or there may be warning
messages sent to the user. Only if the user fails to respond to these
symptoms will malloc() actually fail.
So handling the failure is a formality only, and there is not much point
uglifying code for an error condition which will never be encountered. So an
abort is reasonable. In fact the most likely cause of failure is probably a
programming error causing a garbage value to be passed to malloc() (if
strlen doesn't have a prototype in scope and size_t isn't an unsigned int,
for example). Once a program is incorrect, there's very little you can do.

However if you are allocating a large amount of memory, then it is likely
that malloc() may fail, so the above doesn't apply.

You're making a lot of unwarranted assumptions.

You're assuming that if malloc() fails, it's because the system as a
whole is short on memory. On many systems, a single process can run
out of memory long before the entire system is having any problems.

You're assuming that "the user" is going to respond to a low memory
warning. On a server, there may not be a user who's able to respond
immediately. On a multi-user system, the user running a particular
program may not be able to do anthing about a warning (if he sees it)
other than notifying an administrator, who may or may not be available
at the moment. And depending on the reason for the low memory
condition, there may not be time to respond between the initial
warning and a crash.

Even if there's a single user able to respond to low memory warning,
the user's failure to do so doesn't relieve the program of its
responsibility to respond properly when memory actually runs out.

If a call to malloc() fails, the program needs to detect the failure
and do whatever recovery is appropriate; the size of the request is
irrelevant. If my text editor, for example, aborts and throws away my
changes on a malloc() failure, I'm not going to be interested in
hearing that it didn't bother recovering because it was only
requesting enough memory for a file name.
 
K

kal

H.A. Sujith said:
If malloc fails what should I do?

Go fishing.

malloc does not fail unless the system as a whole is crashing.
It either allocates or does not allocate memory. As has been
pointed out in numerous threads on here, it is a good practice
to test the return value of malloc. By testing, it is meant
that if memory has not been allocated then a different set of
operations will be executed by the program. What those
operations are depends on who is buying your program.
1. Exit imediately.

NO. The only situation in which this is acceptable is that
the program is not able to initialize itself. But such
conditions are outside the scope of the program. Note that
every C program is guaranteed at least 32/64 KB of memory.
2. Print an error message (or put a log entry) and exit.
3. Print an error message (or put a log entry) and continue
execution (after possibly recovering from the error).

Either or both, depending upon your proclivities. Or a number
of other alternatives. In all cases you MUST shut the program
down GRACEFULLY. Hopefully you had already allocated sufficient
resources required for program shutdown.

If you had not pre-allocated resourses required for program
shutdown then you are in exalted company; like Abhimanyu, who
knew how to get in and not how to get out.
Printing an error message might be difficult in a graphical environment.

Not at all. At the least you should have a "status bar" or some
such pre-allocated resource using which you can display messages.
(Note that "stderr" comes pre-allocated.)
 
B

brian

Arto said:
brian said:
there
doesn't seem to be a standard as to whether or not errno is set when
malloc() fails.


SUSv3 has this to say:

---
RETURN VALUE

Upon successful completion with size not equal to 0, malloc() shall
return a pointer to the allocated space. If size is 0, either a null
pointer or a unique pointer that can be successfully passed to free()
shall be returned. Otherwise, it shall return a null pointer [CX]
and set errno to indicate the error.
If the implementation follows the standards, the above is what I get
(that ENOMEN is set) from the malloc() man page in openBSD. However,
in the man page in linux, there was no mention of ENOMEM being set,
and I couldn't get malloc() to fail in linux even using setrlimit().

Now, you have to test for how much the implementation follows any
standard and what standards are followed, which makes portability a pain.

And per the scope of this newsgroup, any extension of ISO C is off
topic. So if the C standard does not require malloc() to set errno,
then we have serious problems when testing for errors. We first
have to determine what standard is followed. We then have to re-write
our error code by implementation or use a lot of #ifndef #if . . .

As you can see, you can find a lot of holes in "portable" software
when it's trying to be ported across a bunch of OS's. And the compiler
won't complain, so you have audit the code.

Brian

P.S. Of course, the definition of what RLIMIT_DATA means is different
between openBSD and linux.
 
M

Malcolm

Keith Thompson said:
If a call to malloc() fails, the program needs to detect the failure
and do whatever recovery is appropriate; the size of the request is
irrelevant. If my text editor, for example, aborts and throws away my
changes on a malloc() failure, I'm not going to be interested in
hearing that it didn't bother recovering because it was only
requesting enough memory for a file name.
The problem is that if the system won't give you a hundred bytes for a file
name, will it give you the memory it needs to call fopen() or the save file
dialog?
Once you are totally out of heap then you are in trouble, unless the system
has been specifically written so that it can function without heap memory.
Anyway, say your program has 10MB of memory available. Given that the
program will run out of memory on a run, the chance of hundred byte
allocation being the one to straddle the boundary is 1 in a hundred
thousand. So if it's a text editor, taking several minutes to run, even if
it runs out of memory on every run, the computer is much more likely to
break than it is to execute your malloc() failure handling code. So no, we
don't need to bother too much what goes into that code.
 
M

Mark McIntyre

The error-retentive approach to this is that if you run out of
memory trying to create a dialog window, you MUST report it by
trying to create a dialog window.

(snip recursive attempt to display error windows).
Thats why a decent OS reserves enough memory to display warning/error
dialogs without invading user space.
What is the return value from malloc() that constitutes a "low memory"
warning?

Well obviously,failure indicates a lower memory warning. How you handle
this is up to you
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,372
Latest member
LucretiaFo

Latest Threads

Top