(too old to reply)
what malloc(0) should returns?
Keith Thompson
2006-12-20 05:05:27 UTC
Post by Stephen Sprunk
Post by Keith Thompson
In my opinion, the behavior defined by the standard for malloc(0) is
not particularly useful.
As with many C oddities, it was more an issue of documenting what
existing pre-ANSI C implementations did, not specifying ideal behavior.
A lot of things in C would be very different if it had been specified
fully before implementations were written -- but it never would have
caught on.
Agreed. I think the gist of the description is that malloc(0) isn't
allowed to blow up; the standard goes into some (possibly unnecessary)
detail about *how* it's not allowed to blow up.

But it seems to me the C89 standard *could* have nailed this down more
tightly than it did. It also mandated that free(NULL) does nothing;
in some existing implementations at the time, it would crash.
Mandating that malloc(0) returns a unique non-null pointer (unless
memory has run out) would have been just as easy; implementations
would just have had to change to meet the new requirement.

It's too late now, I suppose.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Keith Thompson
2006-12-20 05:07:18 UTC
Post by WaterWalk
*sniped* <
A quick test of a few systems I happen to have immediate access to
shows that all of them either return a null pointer, or return
distinct values on two successive calls to malloc(0).
If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that
the returned pointer shall not be used to access an object.
One aspect of the behavior of malloc() with a non-zero size is that
successive calls return unique values. My interpretation is that this
same behavior is required for non-null results of malloc(0).
The simplest way to implement this is to quietly translate "malloc(0)"
to "malloc(1)".
Does this imply that if an implementation makes malloc(0) return a
non-null pointer, this pointer shall be free()d?
What do you mean by "shall"?

There's no requirement to free() any malloc()ed pointer; terminating a
program without free()ing anything is perfectly acceptable as far as
the standard is concerned.

It's true that the result returned by malloc(0) *may* be passed to
free().
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
jaysome
2006-12-20 07:36:29 UTC
Post by Serve Laurijssen
Post by jaysome
On Mon, 18 Dec 2006 16:29:02 +0000, Richard Heathfield
The last sentence in the above quote is meant for your own good, and
has nothing to do with how the OS might misbehave (though it could).
All WIN32 platforms--95/98/ME/NT/2K/XP/2003/Vista/32/64--gracefully
handle null pointer dereferences.
depends if you call access violations graceful ;)
To me, "graceful" in Windows means no BSOD, just like "graceful" in
*NIX means no kernel panic :^)

Best regards
--
jay
Chris Dollin
2006-12-20 08:46:36 UTC
Post by CBFalconer
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.
No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.
I'm thinking, but I can't see an anomaly. I'm probably just being
dim.
You snipped one that I showed earlier.
Hell's teeth, man, cut me some slack -- it's nearly Christmas. I
/did not see/ an anomaly. Write the thing in a reply and explain
what the problem is. It's probably too obvious for me to be able
to see it without help.
--
Chris "HO. HO. HO." Dollin
Nit-picking is best done among friends.
Chris Dollin
2006-12-20 08:55:50 UTC
Post by Chris Torek
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.
No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.
I'm thinking, but I can't see an anomaly. I'm probably just being
dim.
Since malloc() is a reserved function name, let me illustrate with
a different function-name. This also lets me use malloc() for the
"hard parts".
(fx:snip)
Post by Chris Torek
Given the obvious preconditions, the behavior of this code is
well-defined (which may suffice to label it "sensible"), but would
it suffice to replicate the Standard's requirements for malloc()?
No, because the Standard says otherwise -- but CB seemed to be
arguing that even without that explicit requirement the unique
magic pointer approach couldn't be made consistent.
--
Chris "HO. HO. HO." Dollin
"I'm still here and I'm holding the answers" - Karnataka, /Love and Affection/
CBFalconer
2006-12-20 14:36:06 UTC
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.
No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.
I'm thinking, but I can't see an anomaly. I'm probably just being
dim.
You snipped one that I showed earlier.
Hell's teeth, man, cut me some slack -- it's nearly Christmas. I
/did not see/ an anomaly. Write the thing in a reply and explain
what the problem is. It's probably too obvious for me to be able
to see it without help.
<Requoted>
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);
(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if
(p1 == p2)".
</requoted>

The anomaly appears if the results of the malloc calls are non-NULL
and not distinct, i.e. non-compliant.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Random832
2006-12-20 15:45:06 UTC
Post by CBFalconer
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.
No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.
I'm thinking, but I can't see an anomaly. I'm probably just being
dim.
You snipped one that I showed earlier.
Hell's teeth, man, cut me some slack -- it's nearly Christmas. I
/did not see/ an anomaly. Write the thing in a reply and explain
what the problem is. It's probably too obvious for me to be able
to see it without help.
<Requoted>
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);
(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged.
Or it might NOT be unchanged, since we've established that in the
implementation method being discussed, malloc(0) is a special case and
not a normal heap pointer.
Post by CBFalconer
Post by Chris Dollin
Post by CBFalconer
Post by Chris Dollin
However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if
(p1 == p2)".
</requoted>
The anomaly appears if the results of the malloc calls are non-NULL
and not distinct, i.e. non-compliant.
WaterWalk
2006-12-24 12:25:03 UTC
Post by Keith Thompson
Post by WaterWalk
*sniped* <
A quick test of a few systems I happen to have immediate access to
shows that all of them either return a null pointer, or return
distinct values on two successive calls to malloc(0).
If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that
the returned pointer shall not be used to access an object.
One aspect of the behavior of malloc() with a non-zero size is that
successive calls return unique values. My interpretation is that this
same behavior is required for non-null results of malloc(0).
The simplest way to implement this is to quietly translate "malloc(0)"
to "malloc(1)".
Does this imply that if an implementation makes malloc(0) return a
non-null pointer, this pointer shall be free()d?
What do you mean by "shall"?
There's no requirement to free() any malloc()ed pointer; terminating a
program without free()ing anything is perfectly acceptable as far as
the standard is concerned.
It's true that the result returned by malloc(0) *may* be passed to
free().
Oh, what I mean is: if a lot of malloc(0) is called and the returned
results are not free()d, then this is still memory leak. Am I right?
Harald van Dijk
2006-12-24 13:58:23 UTC
Post by WaterWalk
Post by Keith Thompson
Post by WaterWalk
Does this imply that if an implementation makes malloc(0) return a
non-null pointer, this pointer shall be free()d?
What do you mean by "shall"?
There's no requirement to free() any malloc()ed pointer; terminating a
program without free()ing anything is perfectly acceptable as far as
the standard is concerned.
It's true that the result returned by malloc(0) *may* be passed to
free().
Oh, what I mean is: if a lot of malloc(0) is called and the returned
results are not free()d, then this is still memory leak. Am I right?
Yes, if you do not free a non-NULL result from malloc, even with a size
of zero, you have a memory leak.
CBFalconer
2006-12-24 16:29:58 UTC
Post by Harald van Dijk
Post by WaterWalk
Post by Keith Thompson
Post by WaterWalk
Does this imply that if an implementation makes malloc(0) return
a non-null pointer, this pointer shall be free()d?
What do you mean by "shall"?
There's no requirement to free() any malloc()ed pointer;
terminating a program without free()ing anything is perfectly
acceptable as far as the standard is concerned.
It's true that the result returned by malloc(0) *may* be passed
to free().
Oh, what I mean is: if a lot of malloc(0) is called and the
returned results are not free()d, then this is still memory leak.
Am I right?
Yes, if you do not free a non-NULL result from malloc, even with
a size of zero, you have a memory leak.
If you stop to think about it the system has to keep track of
allocations somewhere, even in the case of a zero size returning
non-NULL, and the only way to signal the release of that
information is via free.
--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Joe Wright
2006-12-24 17:10:26 UTC
Post by CBFalconer
Post by Harald van Dijk
Post by WaterWalk
Post by Keith Thompson
Post by WaterWalk
Does this imply that if an implementation makes malloc(0) return
a non-null pointer, this pointer shall be free()d?
What do you mean by "shall"?
There's no requirement to free() any malloc()ed pointer;
terminating a program without free()ing anything is perfectly
acceptable as far as the standard is concerned.
It's true that the result returned by malloc(0) *may* be passed
to free().
Oh, what I mean is: if a lot of malloc(0) is called and the
returned results are not free()d, then this is still memory leak.
Am I right?
Yes, if you do not free a non-NULL result from malloc, even with
a size of zero, you have a memory leak.
If you stop to think about it the system has to keep track of
allocations somewhere, even in the case of a zero size returning
non-NULL, and the only way to signal the release of that
information is via free.
Hi Chuck. Merry Christmas.

If I were King, the argument to malloc would be defined > 0. An argument
0 would force a malloc failure and a NULL return. free(NULL) is harmless
and so, voila, no problem.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
CBFalconer
2006-12-24 18:31:03 UTC
... snip ...
Post by Joe Wright
Post by CBFalconer
If you stop to think about it the system has to keep track of
allocations somewhere, even in the case of a zero size returning
non-NULL, and the only way to signal the release of that
information is via free.
If I were King, the argument to malloc would be defined > 0.
An argument 0 would force a malloc failure and a NULL return.
free(NULL) is harmless and so, voila, no problem.
Bad idea. The system may be used to process variable length data,
which may be empty. This size can be coming in as a parameter to
some routine or other. You don't want to have to test all sorts of
special cases in that routine. Although with the existing C
standard you probably have to:

if (!sz) sz++;
if (!(p = malloc(sz)) failure();
else carryon();

which is why I consider systems that return distinct pointers for
malloc(0) superior. They will forgive forgetting to make the
preliminary check.
--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Keith Thompson
2006-12-24 19:33:24 UTC
Post by CBFalconer
... snip ...
Post by Joe Wright
Post by CBFalconer
If you stop to think about it the system has to keep track of
allocations somewhere, even in the case of a zero size returning
non-NULL, and the only way to signal the release of that
information is via free.
If I were King, the argument to malloc would be defined > 0.
An argument 0 would force a malloc failure and a NULL return.
free(NULL) is harmless and so, voila, no problem.
Bad idea. The system may be used to process variable length data,
which may be empty. This size can be coming in as a parameter to
some routine or other. You don't want to have to test all sorts of
special cases in that routine. Although with the existing C
if (!sz) sz++;
if (!(p = malloc(sz)) failure();
else carryon();
which is why I consider systems that return distinct pointers for
malloc(0) superior. They will forgive forgetting to make the
preliminary check.
In other words, they will fail to diagnose the failure to make the
required check. How friendly.

If I were King, the behavior of malloc(0) would be well-defined. I
might flip a coin to decide *how* it's defined. Heads (i.e., my
portrait) means it's equivalent to malloc(1), except that the pointer
may not be dereferenced; tails means malloc(0) returns a null pointer.
The coin toss would occur only once, and would determine the rule to
be written in the standard. Sufficient bribery might induce me to use
a weighted coin.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
P.J. Plauger
2006-12-25 00:23:42 UTC
Post by Keith Thompson
Post by CBFalconer
... snip ...
Post by Joe Wright
Post by CBFalconer
If you stop to think about it the system has to keep track of
allocations somewhere, even in the case of a zero size returning
non-NULL, and the only way to signal the release of that
information is via free.
If I were King, the argument to malloc would be defined > 0.
An argument 0 would force a malloc failure and a NULL return.
free(NULL) is harmless and so, voila, no problem.
Bad idea. The system may be used to process variable length data,
which may be empty. This size can be coming in as a parameter to
some routine or other. You don't want to have to test all sorts of
special cases in that routine. Although with the existing C
if (!sz) sz++;
if (!(p = malloc(sz)) failure();
else carryon();
which is why I consider systems that return distinct pointers for
malloc(0) superior. They will forgive forgetting to make the
preliminary check.
In other words, they will fail to diagnose the failure to make the
required check. How friendly.
If I were King, the behavior of malloc(0) would be well-defined. I
might flip a coin to decide *how* it's defined. Heads (i.e., my
portrait) means it's equivalent to malloc(1), except that the pointer
may not be dereferenced; tails means malloc(0) returns a null pointer.
The coin toss would occur only once, and would determine the rule to
be written in the standard. Sufficient bribery might induce me to use
a weighted coin.
But what happened instead was much worse. I fought for several meetings
to have malloc(0) return a unique non-null pointer -- just as the Unix
implementation had been doing since day one, not to mention ours (then
Whitesmiths) and all others I knew about. As CBFalconer observed, a
zero-size dynamic array is a naturally occuring thing, just like while
loops that loop zero times. But for some reason Larry Rosler argued
vehemently for malloc(0) being an error, even though this was not in
the best interests of Bell Labs, his employer. By the time I'd convinced
Rosler of my view, most of the committee had grown tired of the whole
debate. So they settled on the worst possible "compromise" -- neither
behavior is guaranteed.

A coin toss would have been a better resolution.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
CBFalconer
2006-12-25 02:51:05 UTC
"P.J. Plauger" wrote:
... snip ...
Post by P.J. Plauger
But what happened instead was much worse. I fought for several meetings
to have malloc(0) return a unique non-null pointer -- just as the Unix
implementation had been doing since day one, not to mention ours (then
Whitesmiths) and all others I knew about. As CBFalconer observed, a
zero-size dynamic array is a naturally occuring thing, just like while
loops that loop zero times. But for some reason Larry Rosler argued
vehemently for malloc(0) being an error, even though this was not in
the best interests of Bell Labs, his employer. By the time I'd convinced
Rosler of my view, most of the committee had grown tired of the whole
debate. So they settled on the worst possible "compromise" -- neither
behavior is guaranteed.
A coin toss would have been a better resolution.
Well, at least now we can point disdainfully at the actual cause of
the problem :-) We can name it the Rosler curse.

BTW, to answer Keiths objection, my nmalloc for DJGPP includes a
provision (non-standard) for injecting run-time hooks, which can
change that behaviour.
--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Richard Tobin
2006-12-25 12:17:05 UTC
Post by P.J. Plauger
So they settled on the worst possible "compromise" -- neither
behavior is guaranteed.
I agree distinct pointers would be better, but the current behaviour
does at least cover the common case: you can malloc an array without
regard for it being possibly empty, and realloc it safely, getting a
real unique value once you need some real memory.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
P.J. Plauger
2006-12-25 14:03:43 UTC
Post by Richard Tobin
Post by P.J. Plauger
So they settled on the worst possible "compromise" -- neither
behavior is guaranteed.
I agree distinct pointers would be better, but the current behaviour
does at least cover the common case: you can malloc an array without
regard for it being possibly empty, and realloc it safely, getting a
real unique value once you need some real memory.
Uh, no. One of the arguments in favor of permitting malloc(0) to be
erroneous was to let some systems diagnose, even trap out, on such
a call. So it's never portably safe to call malloc(0), and it's never
a sure thing that it'll be treated as an error. Everybody loses.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Richard Tobin
2006-12-25 15:44:07 UTC
Post by P.J. Plauger
Post by Richard Tobin
I agree distinct pointers would be better, but the current behaviour
does at least cover the common case: you can malloc an array without
regard for it being possibly empty, and realloc it safely, getting a
real unique value once you need some real memory.
Uh, no. One of the arguments in favor of permitting malloc(0) to be
erroneous was to let some systems diagnose, even trap out, on such
a call. So it's never portably safe to call malloc(0), and it's never
a sure thing that it'll be treated as an error. Everybody loses.
I think you're misremembering. The standard requires malloc(0) to
return either a distinct pointer or NULL. It's not allowed to treat
it as an error.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
P.J. Plauger
2006-12-25 16:33:31 UTC
Post by Richard Tobin
Post by P.J. Plauger
Post by Richard Tobin
I agree distinct pointers would be better, but the current behaviour
does at least cover the common case: you can malloc an array without
regard for it being possibly empty, and realloc it safely, getting a
real unique value once you need some real memory.
Uh, no. One of the arguments in favor of permitting malloc(0) to be
erroneous was to let some systems diagnose, even trap out, on such
a call. So it's never portably safe to call malloc(0), and it's never
a sure thing that it'll be treated as an error. Everybody loses.
I think you're misremembering. The standard requires malloc(0) to
return either a distinct pointer or NULL. It's not allowed to treat
it as an error.
So it seems. The C Standard didn't always end up saying exactly
what the committee decided by consensus.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
av
2006-12-25 16:45:54 UTC
Post by Keith Thompson
Post by CBFalconer
... snip ...
Post by Joe Wright
Post by CBFalconer
If you stop to think about it the system has to keep track of
allocations somewhere, even in the case of a zero size returning
non-NULL, and the only way to signal the release of that
information is via free.
If I were King, the argument to malloc would be defined > 0.
An argument 0 would force a malloc failure and a NULL return.
free(NULL) is harmless and so, voila, no problem.
Bad idea. The system may be used to process variable length data,
which may be empty. This size can be coming in as a parameter to
some routine or other. You don't want to have to test all sorts of
special cases in that routine. Although with the existing C
if (!sz) sz++;
if (!(p = malloc(sz)) failure();
else carryon();
which is why I consider systems that return distinct pointers for
malloc(0) superior. They will forgive forgetting to make the
preliminary check.
In other words, they will fail to diagnose the failure to make the
required check. How friendly.
If I were King, the behavior of malloc(0) would be well-defined. I
might flip a coin to decide *how* it's defined. Heads (i.e., my
portrait) means it's equivalent to malloc(1), except that the pointer
may not be dereferenced; tails means malloc(0) returns a null pointer.
The coin toss would occur only once, and would determine the rule to
be written in the standard. Sufficient bribery might induce me to use
a weighted coin.
why standard says should be: malloc(0)==0 or malloc(0) has to point
some data whose access is illegal

why malloc(0)!=0 has to point to some data
(i.e. "(char*)malloc(0)"
has some memory, but access to it is illegal)?

in how i see
malloc(0) has to return "p" pointer
|header|
^
p
where *(char*)p has to segfault and p should not have memory reserved
for programme

< Previous Page Next Page >
Page 4 of 5