xmalloc

B

Ben Pfaff

Also what does the x mean in xmalloc? Iv'e seen it numerous of
times in sources.

"exit" maybe? Typical implementations call exit if memory cannot
be obtained.
 
K

Keith Thompson

Eric Sosman said:
Keith Thompson wrote On 06/26/07 00:05,:

malloc() is permitted to call exit()? When did
that happen?

Whoops, never mind.

I think what I meant is that the behavior of xmalloc *when it
succeeds* is consistent with the allowed behavior of malloc.
 
C

CBFalconer

Eric said:
Keith Thompson wrote On 06/26/07 00:05,:
.... snip ...

malloc() is permitted to call exit()? When did that happen?

He must be using Microsoft compilers :)
 
K

Keith Thompson

pete said:
This portable code:

http://www.mindspring.com/~pfilandr/C/get_line/get_line.c

has a malloc(0) call,
and does assume that a non-null result may be returned.

It looks like I managed to pack a lot of ambiguity into that sentence.

What I meant is that no portable code can assume that a successful
malloc(0) will always return a non-null result; if malloc(0) returns
NULL, it may or may not indicate that you've run out of memory.

The xmalloc implementation being discussed behaves very differently
from malloc on failure (it aborts the program). The issue is that
xmalloc(0) invokes malloc(1). That particular feature doesn't prevent
xmalloc from being a drop-in replacement for malloc (though aborting
the program certainly does). A valid implementation may treat
malloc(0) as exactly equivalent to malloc(1). malloc(0) is
*permitted* to return NULL even if there's plenty of memory available;
no portable code can assume either that malloc takes advantage of this
permission, or that it doesn't.

Due to the flexibility in the standard's requirement for malloc(0),
xmalloc has to translate malloc(0) into malloc(1); otherwise, there'd
be no way for xmalloc(0) to decide whether to abort the program. (I'm
assuming here that aborting the program on failure is a requirement
for xmalloc.)
 
K

Keith Thompson

CBFalconer said:
Then that code is not portable.

Not at all. It assumes that a non-null result *may* be returned; more
precisely, it allows for that possibility.

Here's the relevant snippet (the INITIAL_BUFFER_SIZE macro expands to 0):

[...]
size = INITIAL_BUFFER_SIZE;
buff = malloc(size);
if (buff == NULL && size != 0) {
[...]

It only assumes failure if malloc returns NULL with a non-zero
argument. If malloc(0) returns NULL, it can't know whether it
succeeded or failed; I assume (without having studied the code) that
it doesn't care.
 
C

Christopher Benson-Manica

Keith Thompson said:
The behavior of xmalloc is still *consistent* with the allowed
behavior of malloc; no portable code can assume that malloc(0) can
return a non-null result.

Right. That's why I took issue with this statement from upthread:

Harald van D?k said:
It depends on the project. Sometimes it matters to have different calls
to malloc(0) return values that do not compare equal, sometimes it
doesn't.

I hope I'm not exceeding the maximum permitted pedantry level here,
but it seems worthwhile to bring it up.
The fact that xmalloc differs from malloc is made clear enough by the
fact that it has a different name.

I suppose I concede the point, but I'd name it something else myself.
 
P

pete

Keith said:
CBFalconer said:
Then that code is not portable.

Not at all. It assumes that a non-null result *may* be returned; more
precisely, it allows for that possibility.

Here's the relevant snippet (the INITIAL_BUFFER_SIZE macro expands to 0):

[...]
size = INITIAL_BUFFER_SIZE;
buff = malloc(size);
if (buff == NULL && size != 0) {
[...]

It only assumes failure if malloc returns NULL with a non-zero
argument. If malloc(0) returns NULL, it can't know whether it
succeeded or failed; I assume (without having studied the code) that
it doesn't care.

It doesn't care.
The result of the malloc call
becomes an argument in either a call to realloc,
or a call to free
 
M

Malcolm McLean

CBFalconer said:
He must be using Microsoft compilers :)
I accidentally created an infinite loop making a small allocations with
Microsoft's free C compiler.
It hung the entire machine for about two minutes, but allowed me to kill the
offending process, and recovered after about another minute.
 
M

Malcolm McLean

Christopher Benson-Manica said:
I take about half of this point. While the code as written did indeed
need to distinguish between failure to allocate non-zero bytes, and
successful allocation of zero bytes (a fact which I missed), it's not
clear to me that xmalloc()'s clients gain anything by essentially
having all calls to malloc(0) replaced by malloc(1). The pointer
returned by malloc(0), if not NULL, can't be used to access an object
anyway, so from xmalloc()'s clients' perspectives, it doesn't much
matter whether xmalloc(0) returns NULL or not:

void *xmalloc( size_t sz ) {
if( sz == 0 ) {
return NULL;
}
/* ... */
}

May as well save the call to malloc(0), if you ask me.
There's quite a strong case for that.
With standard malloc() the rule is an easy way of introducing a bug, as you
write

char *buff = malloc(width * height);
if(!buff)
{
/* failure code */
}

however maybe you want to be able to handle zero-dimensioned tables in
normal flow control.

However with xmalloc() we never need the check, so the problem doesn't
arise.
 
B

Ben Pfaff

Malcolm McLean said:
With standard malloc() the rule is an easy way of introducing a bug,
as you write

char *buff = malloc(width * height);
if(!buff)
{
/* failure code */
}

however maybe you want to be able to handle zero-dimensioned tables in
normal flow control.

Another peril of such code is the tendency to forget that width *
height can overflow. I used to ignore this possibility entirely;
these days, I generally use helper functions that carefully check
multiplications and additions for overflow.
 

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,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top