please check macro

R

Ralph A. Moeritz

Hello,

I have a macro called XMALLOC. It feels hacked and dirty
and I'm not even sure if its valid C (gcc accepts it, and
it _seems_ to work - but that could be co-incident). Any
suggestions on how to improve it?

Thanks,
Ralph


void *xMaLlOcTmP001_ = NULL;

#define XMALLOC( size ) \
( xMaLlOcTmP001_ = malloc( size ) ) \
? xMaLlOcTmP001_ \
: ( fprintf( stderr, "malloc() failed near %s:%d\n", \
__FILE__, __LINE__ ), \
exit( EXIT_FAILURE ), NULL )
 
J

Jens.Toerring

Ralph A. Moeritz said:
I have a macro called XMALLOC. It feels hacked and dirty
and I'm not even sure if its valid C (gcc accepts it, and
it _seems_ to work - but that could be co-incident). Any
suggestions on how to improve it?
void *xMaLlOcTmP001_ = NULL;
#define XMALLOC( size ) \
( xMaLlOcTmP001_ = malloc( size ) ) \
? xMaLlOcTmP001_ \
: ( fprintf( stderr, "malloc() failed near %s:%d\n", \
__FILE__, __LINE__ ), \
exit( EXIT_FAILURE ), NULL )

Looks as if it should work. But since malloc() is an expensive
operation anyway why not make it a function? Something like

void *checked_malloc( size_t size, char *file_name, int line_number )
{
void *new;

if ( ( new = malloc( size ) ) == NULL ) {
fprintf( stderr, "malloc() failed near %s:%d\n",
file_name, line_number );
exit( EXIT_FAILURE );
}

return new;
}

and then use that to replace the normal malloc() by

#defined malloc( size ) checked_malloc( size, __FILE__, __LINE__ )

I guess that looks a bit less like a dirty hack, should work
the same and you can use the normal malloc() in your code,
which might make things easier to read.

Regards, Jens
 
R

Richard Bos

Ralph A. Moeritz said:
void *xMaLlOcTmP001_ = NULL;

#define XMALLOC( size ) \
( xMaLlOcTmP001_ = malloc( size ) ) \
? xMaLlOcTmP001_ \
: ( fprintf( stderr, "malloc() failed near %s:%d\n", \
__FILE__, __LINE__ ), \
exit( EXIT_FAILURE ), NULL )

Technically I can't find anything wrong with it at first glance, but I'd
advise against downright terminating the program (and losing all work
done with it up to that point) just because memory is running low.

Richard
 
M

Michael Knaup

Ralph said:
Hello,

I have a macro called XMALLOC. It feels hacked and dirty
and I'm not even sure if its valid C (gcc accepts it, and
it _seems_ to work - but that could be co-incident). Any
suggestions on how to improve it?

Thanks,
Ralph


void *xMaLlOcTmP001_ = NULL;

#define XMALLOC( size ) \
( xMaLlOcTmP001_ = malloc( size ) ) \
? xMaLlOcTmP001_ \
: ( fprintf( stderr, "malloc() failed near %s:%d\n", \
__FILE__, __LINE__ ), \
exit( EXIT_FAILURE ), NULL )

This code may lead to an error if NULL is not of type (void*) cause the
conditiopnal operator requires both "results" to be the same type. To solve
this problem just add an cast ( fpri... , (void*)NULL)
 
K

Keith Thompson

Technically I can't find anything wrong with it at first glance, but I'd
advise against downright terminating the program (and losing all work
done with it up to that point) just because memory is running low.

There are basically 3 ways to handle a malloc() failure. In order of
increasing difficulty:

1. Ignore the error and blindly keep going.

2. Abort the program immediately.

3. Recover.

Once you've run out of memory, just about anything else you try to do
is likely to fail. For example, you might try to update a file you've
been working on, but the lack of memory could interfere with the
update code, leaving the file in worse shape than if you had just
aborted.

Depending on the application, it's often best to arrange for the
program to be safely abortable at any random point. This minimizes
the damage from any possible failure, including a power failure (which
you can't very well recover from unless you have hardware support).

Another approach is to malloc() a sizeable chunk of memory when the
program starts up; if a later malloc() fails, free the initial chunk,
do some cleanup (hoping the runtime system is smart enough to use the
memory you just freed), and abort.

In some cases a malloc() failure might trigger a fallback to another
algorithm that uses less memory and more time, but I think such cases
are rare.
 
C

CBFalconer

Keith said:
.... snip ...

There are basically 3 ways to handle a malloc() failure. In order
of increasing difficulty:

1. Ignore the error and blindly keep going.

2. Abort the program immediately.

3. Recover.

1) is unlikely to produce anything useful. 2) at least has the
advantage of telling the user "I can't do that", and may often be
the only option. 3)s feasibility is highly dependent on what the
program is intended to do.

Many systems have the general form:

REPEAT
Gobble data until no more or full.
If full leave a mark about how far we got.
Massage what we have.
Clean up.
UNTIL no more.

in which case the malloc failure is the full signal. The repeat
may well be manual.

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
R

Richard Bos

Keith Thompson said:
There are basically 3 ways to handle a malloc() failure. In order of
increasing difficulty:

1. Ignore the error and blindly keep going.

2. Abort the program immediately.

3. Recover.

Once you've run out of memory, just about anything else you try to do
is likely to fail.

This is not necessarily true. For example, in a graphics program, if the
command "enlarge picture to 81920x40960 pixels" runs out of memory, you
may still be able to work with the 2048x1024 pixels you already have.
Depending on the application, it's often best to arrange for the
program to be safely abortable at any random point.

True enough, that's a better solution, where available.
In some cases a malloc() failure might trigger a fallback to another
algorithm that uses less memory and more time, but I think such cases
are rare.

Even so, IMO the decision to abort the program should be made at a
higher level than in a malloc() macro.

Richard
 

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,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top