473,378 Members | 1,605 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

??alloc(0) - std interpretation


7.20.3#1
[...] 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.

Then the ??alloc() functions are described in 7.20.3.* .

Does the above quote's "either, or" apply to all the ??alloc() functions
*together* or *separately*?

Example:
In GNU libc malloc(0)!=NULL, but realloc(..., 0)==NULL. Is this
compliant?

TIA

--
Stan Tobias
Nov 14 '05 #1
7 1825
<sN*******@amu.edu.pl> wrote in message news:2g************@uni-berlin.de...

7.20.3#1
[...] 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.

Then the ??alloc() functions are described in 7.20.3.* .

Does the above quote's "either, or" apply to all the ??alloc() functions
*together* or *separately*?

Example:
In GNU libc malloc(0)!=NULL, but realloc(..., 0)==NULL. Is this
compliant?


realloc(ptr, 0) is defined to be equal to free(ptr) and return NULL.

Since the 'either' doesn't make sense in the case of realloc(), the logical
conclusion is that the non-NULL return is allowed for malloc() independently
of how realloc() behaves.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

Nov 14 '05 #2
Stephen Sprunk <st*****@sprunk.org> wrote:
realloc(ptr, 0) is defined to be equal to free(ptr) and return NULL.
No, it's nowhere defined like that. It's not even equivalent of free()
(google for "realloc equivalent free"), although it may be implemented
this way.

In C89 there is a clause: " If size is zero and ptr is not a null
pointer, the object it points to is freed.", but this does not mean
that realloc(..., 0) merely performs free(); IMO it requires realloc()
to free the original buffer irrespective of whether subsequent zero-sized
allocation succeeds or not (in opposition to non-zero size reallocation,
where the original buffer cannot change on failure). Both C89 and C99
agree on that, only they're differently worded.

In general, not freeing realloc(..., 0) result leads to memory leak.
Since the 'either' doesn't make sense in the case of realloc(), the logical
conclusion is that the non-NULL return is allowed for malloc() independently
of how realloc() behaves.


Provided your assumption was wrong, the conclusion is irrelevant.
But my question equally might apply to malloc()/calloc() implementation.
So, can malloc(0)==NULL and calloc(0,0)!=NULL ?

--
Stan Tobias
Nov 14 '05 #3

On Mon, 17 May 2004 sN*******@amu.edu.pl wrote:

In general, not freeing realloc(..., 0) result leads to memory leak.
Correct. Implementations are allowed to return NULL from
realloc(..., 0), in which case the free() does nothing; but they
are also allowed to return not-NULL, in which case the free() is
required.
But my question equally might apply to malloc()/calloc() implementation.
So, can malloc(0)==NULL and calloc(0,0)!=NULL ?


Sure. Do you have any reason to suspect otherwise? [In
practice, this will never happen; it's purely a QoI issue.]

-Arthur
Nov 14 '05 #4
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
On Mon, 17 May 2004 sN*******@amu.edu.pl wrote:
But my question equally might apply to malloc()/calloc() implementation.
So, can malloc(0)==NULL and calloc(0,0)!=NULL ?
Sure. Do you have any reason to suspect otherwise? [In
Yes, reading 7.20.3 in n869.txt, indeed I do.

All sentences in 7.20.3#1 apply equally to all ??alloc() fns. Further,
"Each such allocation shall yield a pointer to an object disjoint from
any other object." applies to the *whole group* of ??alloc() fns (ie. I
need not worry that malloc() and calloc() might overlap). I don't see why
"If the size of the space requested is zero, [...]" should have different
context; if it was meant to have, the unambiguous way to express this
would be to repeat this clause at each ??alloc() description.

BTW, I don't understand the last sentence there: "The value of a pointer
that refers to freed space is indeterminate."; where does it apply to?
practice, this will never happen; it's purely a QoI issue.]


Well, it does happen to malloc() vs. realloc(). What I mean to say,
is that no QoI shall save me any work for portable code.

The practical difference is for strict error detection. If for zero
allocation size return value may differ for each ??alloc(), then I have
to write different error-checking code for each of them.

For example:

#if MALLOC_0_NULL
# define malloc_error(ret, size) (ret == NULL && size > 0)
#else
# define malloc_error(ret, size) (ret == NULL)
#endif

#if CALLOC_0_NULL
# define calloc_error(ret, nmemb, size) (ret == NULL && nmemb > 0 && size > 0)
#else
# define calloc_error(ret, nmemb, size) (ret == NULL)
#endif

#if REALLOC_PTR_0_NULL
# define realloc_error(ret, ptr, size) \
(ptr == NULL ? malloc_error(ret, size) : ret == NULL && size > 0)
#else
# define realloc_error(ret, ptr, size) \
(ptr == NULL ? malloc_error(ret, size) : ret == NULL)
#endif

(I wrote those from scratch, hope there's no error)

MALLOC_0_NULL, CALLOC_0_NULL, REALLOC_PTR_0_NULL have to be known for
every implementation; there seems to be no "general" solution, ie.
without knowing them.

--
Stan Tobias
Nov 14 '05 #5
On 17 May 2004 16:58:48 GMT, sN*******@amu.edu.pl wrote in
comp.lang.c:

7.20.3#1
[...] 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.

Then the ??alloc() functions are described in 7.20.3.* .

Does the above quote's "either, or" apply to all the ??alloc() functions
*together* or *separately*?

Example:
In GNU libc malloc(0)!=NULL, but realloc(..., 0)==NULL. Is this
compliant?

TIA


I've seen several replies and your responses in this thread, so I'll
just add three points:

1. Since the behavior is implementation-defined, you should consult
the implementation's required documentation.

2. The proper place to ask for definitive interpretation of the
wording of the standard is news:comp.std.c, not here. Several members
of the standards committees read and respond there regularly.

3. N869 is not the standard, and the wording you quote (farther down
the thread, I admit) is no longer where you found it. It has moved
somewhere else. But the statement that freeing a pointer renders it
indeterminate merely provides a way of stating that any use of its
value, even if not to dereference, produces undefined behavior, as
does the use of any indeterminate value.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #6

On Mon, 18 May 2004 sN*******@amu.edu.pl wrote:

Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
On Mon, 17 May 2004 sN*******@amu.edu.pl wrote:

So, can malloc(0)==NULL and calloc(0,0)!=NULL ?
Sure. Do you have any reason to suspect otherwise? [In


Yes, reading 7.20.3 in n869.txt, indeed I do.


[I'm reading N869, too, BTW. I don't have a copy of the Standard.]
All sentences in 7.20.3#1 apply equally to all ??alloc() fns. Further,
"Each such allocation shall yield a pointer to an object disjoint from
any other object." applies to the *whole group* of ??alloc() fns (ie. I
need not worry that malloc() and calloc() might overlap).
Naturally.
I don't see why "If the size of the space requested is zero, [...]"
should have different context; if it was meant to have, the unambiguous
way to express this would be to repeat this clause at each ??alloc()
description.
Suppose the implementation's default behavior upon malloc(0) is to
return a newly allocated chunk of memory containing no payload -- just
a header and footer (speaking from the POV of the malloc implementor,
not the C programmer). Now suppose I write

while (1) {
if (malloc(0) == NULL) break;
}
puts("malloc returned NULL");

Do you see now that at some point 'malloc(0)' *MUST* return NULL,
no matter what it normally returns?
Since we don't know when the system will run out of free memory,
we can never say with certainty when 'malloc' (or 'calloc') will
return NULL.

BTW, I don't understand the last sentence there: "The value of a pointer
that refers to freed space is indeterminate."; where does it apply to?
free(p);
/* p is now indeterminate, and its value must not be used */
See the recent thread in Google Groups' archives if you still have
questions. This is a RAQ (Recently Asked Question). :)

practice, this will never happen; it's purely a QoI issue.]


Well, it does happen to malloc() vs. realloc(). What I mean to say,
is that no QoI shall save me any work for portable code.


I meant: If any real implementation made the following code
print "Yes", then that real implementation would be considered to
have a poor "Quality of Implementation."

#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (malloc(0) != NULL) return 0;
if (calloc(0,0) == NULL) return 0;
puts("Yes");
}

As for "portability," this has little to do with it. See below.
The practical difference is for strict error detection. If for zero
allocation size return value may differ for each ??alloc(), then I have
to write different error-checking code for each of them.

For example:

#if MALLOC_0_NULL
# define malloc_error(ret, size) (ret == NULL && size > 0)
#else
# define malloc_error(ret, size) (ret == NULL)
#endif
Simply '#define malloc_error(ret,size) (ret == NULL)' and then
make sure to error-check the input to 'malloc' so that you never
pass 0 to 'malloc' to begin with. If you're dealing with legacy
code, rather than writing your own, you can always put

#define safe_malloc(b) malloc((b)+1) /* guaranteed nonzero */
#define malloc_error(p, z) (0 == (p)) /* NULL return from malloc */

and then do a search-and-replace of 'malloc' by 'safe_malloc'.
But that's a very silly way to ensure portability. It would be
much better to write sensible, non-zero-allocating code in the
first place.
MALLOC_0_NULL, CALLOC_0_NULL, REALLOC_PTR_0_NULL have to be known for
every implementation; there seems to be no "general" solution, ie.
without knowing them.


The general solution is to write code that doesn't depend on
quirks or corner cases in the implementation.

HTH,
-Arthur

Nov 14 '05 #7
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
[I'm reading N869, too, BTW. I don't have a copy of the Standard.]
Prompted by Jack Klein's answer, I've finally bought the C99 Standard
myself. Indeed, the wording differs slightly from n869.txt, but it
chages nothing in the discussion.
[snip]
while (1) {
if (malloc(0) == NULL) break;
}
puts("malloc returned NULL");

Do you see now that at some point 'malloc(0)' *MUST* return NULL,
no matter what it normally returns?
But that's an error return, right? All I was saying was in the case
of *successful* return.

BTW, I don't understand the last sentence there: "The value of a pointer
that refers to freed space is indeterminate."; where does it apply to?

[snip] questions. This is a RAQ (Recently Asked Question). :)
I'm sorry. I remember even seeing that discussion in my news-reader.
Thank you for pointing this out to me, I'll read it later.

practice, this will never happen; it's purely a QoI issue.]


Well, it does happen to malloc() vs. realloc(). What I mean to say,
is that no QoI shall save me any work for portable code.


I meant: If any real implementation made the following code
print "Yes", then that real implementation would be considered to
have a poor "Quality of Implementation."

[snipped code]

Yes, I agree it would be absurd if malloc(0)!=calloc(0,0). What I wanted
to point out is that from my POV it might be considered equally absurd
that malloc(0)!=realloc(p,0). realloc(p,0) is not free(p), it "allocates"
zero-sized buffer, same way as malloc(0) does. If my interpretation
was right, then there wouldn't be such asymmetry between strict error
checking for malloc() and realloc():

/* works for all ??alloc()s */
#if ALLOC_0_NULL
# define alloc_error(ret, size) (ret != NULL && size > 0)
#else
# define alloc_error(ret, size) (ret != NULL)
#endif
Simply '#define malloc_error(ret,size) (ret == NULL)' and then
make sure to error-check the input to 'malloc' so that you never
pass 0 to 'malloc' to begin with. If you're dealing with legacy
code, rather than writing your own, you can always put

#define safe_malloc(b) malloc((b)+1) /* guaranteed nonzero */
#define malloc_error(p, z) (0 == (p)) /* NULL return from malloc */

and then do a search-and-replace of 'malloc' by 'safe_malloc'.
But that's a very silly way to ensure portability. It would be
much better to write sensible, non-zero-allocating code in the
first place.


One way or another, you have to end up writing your own wrapper library
(that does not even have to depend on the implementation!), which renders
the Standard somewhat "useless" :)

Another way is to only check for:
#define alloc_error(ret, size) (ret == NULL && size > 0)
ie. always assume malloc(0)==NULL convention. This is what I call relaxed
error checking, and will work when malloc(0)!=NULL (if the rest of the
code is portable, it must be prepared for accepting NULL and won't depend
on distinct returned pointers).

What I want for now is a portable (by that I understand correct wrt Std)
code that works with Standard Library; I want to know what the Standard
actually says, and what is deviation from it. The second motivation
is simply curiosity.

Thank you for your answers. Encouraged by Jack Klein (I thank him too)
I'm going to re-ask this question in CSC.

--
Stan Tobias
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Adam Hartshorne | last post by:
Hi All, I have the strangest problem, and at an end to try and explain it/know what to do. I have a program written in c++ using visual studio 7.1. It was all working no problems, then after...
6
by: B. Gandhi | last post by:
Hi friends I have a query regarding memory allocation deallocation in C. It is as follows: char *path = getenv("PATH"); In this call to getenv(), where does the returned string stored?...
10
by: Ryan Wang | last post by:
Hi, here is the function: int sum(int a,int b) { int c; c = a + b; return c; }
3
by: -DG- | last post by:
I'm still trying to figure out some of the nuances of access to legacy Win32 DLLs. I need to alloc buffers to be used by the Win32 DLLs. I know that pinning a managed pointer can lead to...
2
by: cnliou | last post by:
Linux 2.4.23 on AMD 450MHz. pgsql 7.4.1 configure --enable-multibyte=UNICODE locale is zh_TW.Big5 IIRC, when I did "initdb -E UNICODE" or "createdb db1", I saw the following message from...
1
by: John Hagstrand | last post by:
Hello, I'm getting the following error when I try to update or insert into a table. This just started happening today. The table has been working fine up to now. The table has 27,000 rows and...
5
by: Janning Vygen | last post by:
Hi, tonight my database got corruppted. before it worked fine. since two days i do the following tasks every night psql -c 'CLUSTER;' $DBNAME psql -c 'VACUUM FULL ANALYZE;' $DBNAME ...
17
by: Joe Smith | last post by:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define BUF_MAX 80 int main (void) { char buf;
1
by: =?Utf-8?B?SkE=?= | last post by:
I use a method for threading that instantiates an object that is a wrapper to a DLL (written in C). The wrapper class is passed a byte array, and then does GCHandle handle =...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.