473,785 Members | 2,424 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

call to malloc with size 0

Neo
Hi Folks,

I've a simple qestion related to dynamic memory allocation in C here is the
code:

#include <stdio.h>

int main()

{

char *p;

if( (p=(char*)mallo c(0)) == NULL)

printf("NULL\n" );

else

printf("Valid Pointer\n");

return 0;

}

Output : "Valid Pointer"

Why this code fragment returns a valid pointer to a memory block???

-Neo


Nov 14 '05
54 7871


Keith Thompson wrote:

This is perfectly acceptable behavior. There are architectures
that have unusable memory ranges within the total possible range
that could be represented by a (void*). A conforming implementation
could choose an available unique value from the unusable range to
return from malloc()/calloc() when the requested size is zero. A
later free() would accept that unusable pointer.

The simplest way for malloc() to return a unique pointer for each
malloc(0) would be for it to change the argument internally to 1:

void *malloc(size_t size)
{
if (size == 0) size = 1;
/* the rest of the function */
}


There's no guarantee that this will return a unique pointer.
Even a malloc of size 1 may fail if the memory resources are
exhausted.
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #31
Al Bowers <xa******@rapid sys.com> writes:
Keith Thompson wrote:

This is perfectly acceptable behavior. There are architectures
that have unusable memory ranges within the total possible range
that could be represented by a (void*). A conforming implementation
could choose an available unique value from the unusable range to
return from malloc()/calloc() when the requested size is zero. A
later free() would accept that unusable pointer.

The simplest way for malloc() to return a unique pointer for each
malloc(0) would be for it to change the argument internally to 1:
void *malloc(size_t size)
{
if (size == 0) size = 1;
/* the rest of the function */
}


There's no guarantee that this will return a unique pointer.
Even a malloc of size 1 may fail if the memory resources are
exhausted.


Which, again, is perfectly acceptable. If the implementation decides
to have malloc(0) return a unique pointer on each call, it can't do so
indefinitely; eventually it will fail by running out of memory, and it
will indicate the failure by returning a null pointer.

The standard (C99 7.20.3p1) says:

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.

Making malloc(0) equivalent to malloc(1) satisfies this.

--
Keith Thompson (The_Other_Keit h) ks***@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.
Nov 14 '05 #32
In <82************ *****@read1.cgo cable.net> "Method Man" <a@b.c> writes:

"Ben Pfaff" <bl*@cs.stanfor d.edu> wrote in message
news:87******* *****@benpfaff. org...
"Method Man" <a@b.c> writes:
> I can't immediately see a practical use in obtaining a valid
> pointer from malloc(0). I would be curious to know how the
> implementation handled dereferencing and type-casting for this
> magical pointer.
Dereferencing the result of malloc(0) yields undefined behavior.


How can you say for certain that it will yield UB? Assuming the pointer
obtained from malloc(0) is unique and valid, it therefore must be pointing
to some valid memory location.


It's the same as with pointers pointing one past the last element of an
array. They're "valid" only in the sense that assigning, converting or
comparing them for equality works normally, but they cannot be
dereferenced. Whether they point to a valid memory location is up to
the implementor (have a look at Electric Fence to see how an
implementation can create invalid memory locations having valid memory
addresses).
I thought only invalid and void pointers
caused UB when dereferenced. Perhaps I am misunderstandin g something.


If the standard says that a pointer value cannot be used to access an
object, attempting to do so results in undefined behaviour. This is
different from an invalid pointer value, which cannot be used at all
without invoking undefined behaviour (except for examining its
representation on a byte by byte basis).

E.g.

char *p = malloc(0);
char *q = malloc(1);
free(q);

At this point, assuming that both malloc calls returned non-null pointers,
p contains a valid pointer value that cannot be dereferenced, while q
contains an invalid pointer value, which cannot be used at all without
invoking undefined behaviour.

Void pointers are in a different category: the attempt to dereference
them is a constraint violation, so a diagnostic is required.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #33


Keith Thompson wrote:
Al Bowers <xa******@rapid sys.com> writes:
Keith Thompson wrote:

The simplest way for malloc() to return a unique pointer for each
malloc(0) would be for it to change the argument internally to 1:
void *malloc(size_t size)
{
if (size == 0) size = 1;
/* the rest of the function */
}


There's no guarantee that this will return a unique pointer.
Even a malloc of size 1 may fail if the memory resources are
exhausted.

Which, again, is perfectly acceptable. If the implementation decides
to have malloc(0) return a unique pointer on each call, it can't do so
indefinitely; eventually it will fail by running out of memory, and it
will indicate the failure by returning a null pointer.

The standard (C99 7.20.3p1) says:

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.

Making malloc(0) equivalent to malloc(1) satisfies this.


Yes, your internal implement satisfies the Standard requirements. Either
a NULL value is returned or a unique pointer value. Your implement
is weighed to the latter.

I was just questioning the wording in your description.
Specifically in the comment:

"The simplest way for malloc() to return a unique pointer for each
malloc(0) would be for it to change the argument internally to 1"

I was equating your word "each" to mean "all".

At some point the implement may be unable to return
a unique pointer(it returns NULL), which means that one cannot
say that every call to malloc(0) will return a unique pointer.

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #34
Al Bowers <xa******@rapid sys.com> writes:
[...]
Yes, your internal implement satisfies the Standard requirements. Either
a NULL value is returned or a unique pointer value. Your implement
is weighed to the latter.

I was just questioning the wording in your description.
Specifically in the comment:

"The simplest way for malloc() to return a unique pointer for each
malloc(0) would be for it to change the argument internally to 1"


You're right, I should have qualified that.

--
Keith Thompson (The_Other_Keit h) ks***@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.
Nov 14 '05 #35
On 18 Nov 2004 15:06:02 GMT
Joona I Palaste <pa*****@cc.hel sinki.fi> wrote:
Method Man <a@b.c> scribbled the following:
<snip>
Fair enough. Although, I can't immediately see a practical use in
obtaining a valid pointer from malloc(0). I would be curious to know
how the implementation handled dereferencing and type-casting for
this magical pointer.


If the C memory model was continuous rather than discrete, then there
would be no problem. In a continuous memory model, pointer values
would only serve as "starting points" of allocated memory, not
allocated memory itself. If you think of the conventional discrete
memory model as labelling boxes with addresses, in a continuous memory
model you don't label the boxes, you label the gaps between them. This
way the malloc() implementation could safely return the same,
non-null, pointer value over and over again from calls to malloc(0),


I don't think this would be allowed. I think that any valid pointer (as
opposed to null pointer) returned by malloc must compare different to
any other object that still exists. I.e.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
void *p1 = malloc(0);
void *p2 = malloc(0);

if (p1 && (p1 == p2))
puts("This should never be printed!");

return 0;
}

Modulo any errors people point out (I've not tried it) I don't believe
the above is allowed to print "This should never be printed!" which it
would with the implementation you describe.
because reserving 0 bytes onward from that gap between boxes doesn't
actually reserve any box at all, and it's the boxes you store stuff
in, not the gaps between them. This is of course very much off-topic
for comp.lang.c but those who have studied real analysis and topology
know what I'm talking about.


I know what you are talking about, I just don't think it is allowed.

One possible way the library could implement malloc(0) returning a
non-null pointer is to treat it as malloc(1), I.e. give you a pointer
to a byte that it really has allocated. After all, a derefference isn't
guaranteed to fail by the standard.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #36
On Thu, 18 Nov 2004 08:49:38 +0530
"Neo" <ti************ ***@yahoo.com> wrote:

<snip not casting the return value of malloc.
invalid cast - what do you mean by saying *invalid cast*. isnt it a
standard practice to cast the pointer returned by the malloc() to
desired type? or how then it can be otherwise like:
p = malloc(0);
???


In C it is standard practice to not cast the value returned by malloc.
There are a few obscure exceptions, an one person who posts here has a
good reason why he (as opposed to everyone else) has to.

If you use a function without a prototype the compiler assumes it
returns an int where as malloc actually returns void*. Thus if, for
example, pointers are returned in A0 (an address register) and ints are
returned in D0 (a data register) then the compiled version of your code
will ignore the pointer returned by malloc and instead convert some
random value that happens to be in D0 to a pointer, this is obviously
likely to cause your program to fail, probably when your boss is
demonstrating the program to a very big potential customer. Such is the
rath of invoking undefined behaviour.

If you don't have the cast and you have forgotten to include stdlib.h
then the compiler is *required* to generating a diagnostic (C99 is
different and a diagnostic is required even with the cast, but I'll bet
you are not using a*conforming* C99 implementation) .

Conversion between void* and other object (not function) pointers is
automatic and does not require a cast.

The prefered (by most of the regulars) method of calling malloc around
here is
p = malloc( n * sizeof *p);

If you search the group you can find lots of discussion on this point.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #37
On Fri, 19 Nov 2004 01:11:17 GMT
Keith Thompson <ks***@mib.or g> wrote:
Da*****@cern.ch (Dan Pop) writes:
[...]
Or, if you prefer macros:

#define XMALLOC(size) malloc(size == 0 ? 1 : size)
#define YMALLOC(size) (size == 0 ? NULL : malloc(size))


Your XMALLOC is probably clearer than the one I came up with, but I'm
going to show it off because I think it's kinda clever.

#define XMALLOC(size) malloc((size) + ((size)==0))

(Yes, I habitually parenthesize references to arguments to
function-like macros; it's easier than figuring out when it isn't
necessary.)


Of course, either macro is a potential problem if you do
p = XMALLOC( size_array[i++] );
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #38
Flash Gordon wrote:

Neo wrote:

<snip not casting the return value of malloc.

invalid cast - what do you mean by saying *invalid cast*. isnt it a
standard practice to cast the pointer returned by the malloc() to
desired type? or how then it can be otherwise like:
p = malloc(0);
???
In C, it is standard practice to not cast the value returned by malloc.
Nonsense!
There are a few obscure exceptions, and one person who posts here
has a good reason why he (as opposed to everyone else) has to.
Lots of people who post here have good rerasons
to cast the pointer returned by the malloc(size_t).
If you use a function without a prototype
Don't do that.
the compiler assumes [that] it returns an int
where as malloc actually returns void*.
Thus if, for example, pointers are returned in A0 (an address register)
and ints are returned in D0 (a data register),
then the compiled version of your code
will ignore the pointer returned by malloc and instead
convert some random value that happens to be in D0 to a pointer,
this is obviously likely to cause your program to fail,
probably when your boss is demonstrating the program
to a very big potential customer.
Such is the rath of invoking undefined behaviour.
FUD

http://en.wikipedia.org/wiki/FUD
If you don't have the cast and you have forgotten to include stdlib.h
then the compiler is *required* to generating a diagnostic
(C99 is different and a diagnostic is required even with the cast,
but I'll bet you are not using a *conforming* C99 implementation) .
Then you should get a C compiler that conforms with this requirement.
There are plenty of them them that do.
Conversion between void* and other object (not function) pointers
is [implicit and] automatic and does not require a cast.

The prefered (by most of the regulars) method
of calling malloc around here is

p = malloc( n * sizeof *p);


This is a matter of style and [poor] taste.

Write:

char* p = (char*)malloc(n *sizeof(char*)) ;

and both C and C++ compilers will accept your code.

Nov 14 '05 #39
On Fri, 19 Nov 2004 15:26:05 -0800
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote:
Flash Gordon wrote:
Neo wrote:

<snip not casting the return value of malloc.

invalid cast - what do you mean by saying *invalid cast*. isnt it a
standard practice to cast the pointer returned by the malloc() to
desired type? or how then it can be otherwise like:
p = malloc(0);
???
In C, it is standard practice to not cast the value returned by
malloc.


Nonsense!
There are a few obscure exceptions, and one person who posts here
has a good reason why he (as opposed to everyone else) has to.


Lots of people who post here have good rerasons
to cast the pointer returned by the malloc(size_t).
If you use a function without a prototype


Don't do that.


Agreed. I even explain below why not.
the compiler assumes [that] it returns an int
where as malloc actually returns void*.
Thus if, for example, pointers are returned in A0 (an address
register) and ints are returned in D0 (a data register),
then the compiled version of your code
will ignore the pointer returned by malloc and instead
convert some random value that happens to be in D0 to a pointer,
this is obviously likely to cause your program to fail,
probably when your boss is demonstrating the program
to a very big potential customer.
Such is the rath of invoking undefined behaviour.


FUD

http://en.wikipedia.org/wiki/FUD


It is entirely real. I've used a 68000 based system that returned
pointers in A0 and ints in D0. Also as you should be aware we are
getting new systems where int and pointers are not the same size,
leading to more systems where it would fail.
If you don't have the cast and you have forgotten to include
stdlib.h then the compiler is *required* to generating a diagnostic
(C99 is different and a diagnostic is required even with the cast,
but I'll bet you are not using a *conforming* C99 implementation) .


Then you should get a C compiler that conforms with this requirement.
There are plenty of them them that do.


Name 5 conforming C99 implementations . I'll start you off with gcc not
being one, since GNU explicitly states that it does not yet conform.
Conversion between void* and other object (not function) pointers
is [implicit and] automatic and does not require a cast.

The prefered (by most of the regulars) method
of calling malloc around here is

p = malloc( n * sizeof *p);


This is a matter of style and [poor] taste.

Write:

char* p = (char*)malloc(n *sizeof(char*)) ;

and both C and C++ compilers will accept your code.


As discussed previously, with very few exceptions there is no good
reason to nead to compile C code as C++, especially since there are
various things which compile and behave differently.

You are, of course, trolling, I only respond so that newbies don't think
I accept your claims. Unless you can name 5 conforming C99
implementations (which should be easy if your claim that there are
plenty were true) then consider any lack of responce to further posts by
you to indicate that I disagree with you.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #40

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

Similar topics

13
83901
by: mike79 | last post by:
hi all.. if I wanted to malloc a struct, say the following: struct myStruct1 { int number; char *string; }
10
2318
by: pembed2003 | last post by:
Hi, If I have the folllowing: char* p = malloc(5); memset(p,-1,5); *p = 0; printf("%d\n",strlen(p)); free(p); It will print 0. Is there a way to retrive the initial size of memory
7
2216
by: Rano | last post by:
/* Hello, I've got some troubles with a stupid program... In fact, I just start with the C language and sometime I don't understand how I really have to use malloc. I've readden the FAQ http://www.eskimo.com/~scs/C-faq/faq.html but it doesn't seem to answer my questions... So, I've made an example behind, with some included questions...
42
2180
by: Joris Adriaenssens | last post by:
This is my first posting, please excuse me if it is off-topic. I'm learning to program in C. It's been almost ten years I've been programming and a lot of things have changed apparently. I understand from other postings that casting a result from malloc isn't good. In the past I have always been casting the malloc. I think it was even necessary. (But that's a long time ago, I hadn't heard of a standard for C these days). Was it...
14
3300
by: Marlene Stebbins | last post by:
At one point in my program I have about a dozen calls to malloc. I want to check for malloc failure, but I don't want to write: if((buffer_x = malloc(BUFSIZE * sizeof(*buffer_x))) == NULL) { exit(EXIT_FAILURE); fprintf(stderr, "malloc failed"); } for each individual call if there is a stylistically better way. How
3
11445
by: Zheng Da | last post by:
Program received signal SIGSEGV, Segmentation fault. 0x40093343 in _int_malloc () from /lib/tls/libc.so.6 (gdb) bt #0 0x40093343 in _int_malloc () from /lib/tls/libc.so.6 #1 0x40094c54 in malloc () from /lib/tls/libc.so.6 It's really strange; I just call malloc() like "tmp=malloc(size);" the system gives me Segmentation fault I want to write a code to do like a dynamic array, and the code is as
18
3319
by: cs | last post by:
This is the function malloc_m() that should be like malloc() but it should find memory leak, and over bound writing in arrays. How many errors do you see? Thank you ******************************************** /* mallocm.c */ /* funzione di libreria per trattamento della memoria e rilevamento errori */ /* uso: c_compiler malloc.c e usare malloc .obj */
3
1437
by: melanieab | last post by:
Hi, I'm having trouble when I leave a tabpage to go on to the next. On Focus Leave, I take a snapshot of that tab. It usually turns out ok, but often, part of the next tabpage will appear in this snapshot (an outline of a picturebox or textbox). Is there anything I can do about this? Thanks!!!! Mel
71
19136
by: desktop | last post by:
I have read in Bjarne Stroustrup that using malloc and free should be avoided in C++ because they deal with uninitialized memory and one should instead use new and delete. But why is that a problem? I cannot see why using malloc instead of new does not give the same result.
0
9647
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9485
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10356
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10098
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
6743
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5390
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5523
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3662
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2890
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.