calloc(1,1) vs. *malloc(1)=0

R

rihad

To make up a proper dynamically allocated empty C string, would it suffice to
say:

return calloc(1, 1);

or am I better off using the longer version

char *p = malloc(1);
if (p) *p = 0;
return p;

? TIA
 
I

Irrwahn Grausewitz

rihad said:
To make up a proper dynamically allocated empty C string, would it suffice to
say:

return calloc(1, 1);

or am I better off using the longer version

char *p = malloc(1);
if (p) *p = 0;
return p;

Both versions may return NULL, which is not a pointer to an empty
string. Unless you expect the caller of your function to check for
NULL you should take appropriate action before returning p.

As for calloc: I always have a funny feeling about this "the space
is initialized to all bits zero" behaviour. That isn't a problem
when you're dealing with unsigned character entitities, but may have
"astonishing results" (to quote the C Rationale) when working with
other types. Thus I stay away from using it at all.

HTH
Regards
 
P

Peter Pichler

rihad said:
To make up a proper dynamically allocated empty C string, would it suffice to
say:

return calloc(1, 1);

or am I better off using the longer version

char *p = malloc(1);
if (p) *p = 0;
return p;

There is no difference between those two, from C's POV.

<OT> Just out of interest, why would you want to do such a thing? :) </OT>
 
P

Peter Pichler

rihad said:
To make up a proper dynamically allocated empty C string, would it suffice to
say:

return calloc(1, 1);

or am I better off using the longer version

char *p = malloc(1);
if (p) *p = 0;
return p;

There is no difference between those two, from C's POV.

<OT> Just out of interest, why would you want to do such a thing? :) </OT>
 
I

Irrwahn Grausewitz

There is no difference between those two, from C's POV.

As long as char is unsigned by default, or it is signed but
doesn't contain padding bits; otherwise the first method might
generate a trap representation by setting *p to all bits zero,
IIRC.

Regards
 
E

Eric Sosman

Irrwahn said:
As long as char is unsigned by default, or it is signed but
doesn't contain padding bits; otherwise the first method might
generate a trap representation by setting *p to all bits zero,
IIRC.

That particular perversion doesn't seem to be possible
in this instance. The Standard describes a string as being
"terminated by [...] the first null character" (7.1.1/1).
The null character is in turn defined as "a byte with all
bits set to zero" (5.2.1/2).

Thus, the byte zeroed by calloc() is in fact the string
terminator.
 
I

Irrwahn Grausewitz

Eric Sosman said:
Irrwahn said:
As long as char is unsigned by default, or it is signed but
doesn't contain padding bits; otherwise the first method might
generate a trap representation by setting *p to all bits zero,
IIRC.

That particular perversion doesn't seem to be possible
in this instance. The Standard describes a string as being
"terminated by [...] the first null character" (7.1.1/1).
The null character is in turn defined as "a byte with all
bits set to zero" (5.2.1/2).

Thus, the byte zeroed by calloc() is in fact the string
terminator.

Yes, you're right, thanks for correcting.

All these recent discussions about padding bits and trap
representations made me somewhat paranoid about that matter.

Regards
 
P

Peter Nilsson

Irrwahn Grausewitz said:
Eric Sosman said:
Irrwahn said:
return calloc(1, 1);
char *p = malloc(1);
if (p) *p = 0;
return p;
There is no difference between those two, from C's POV.

As long as char is unsigned by default, or it is signed but
doesn't contain padding bits; otherwise the first method might
generate a trap representation by setting *p to all bits zero,
IIRC.

That particular perversion doesn't seem to be possible
in this instance. The Standard describes a string as being
"terminated by [...] the first null character" (7.1.1/1).
The null character is in turn defined as "a byte with all
bits set to zero" (5.2.1/2).

Thus, the byte zeroed by calloc() is in fact the string
terminator.

Yes, you're right, thanks for correcting.

All these recent discussions about padding bits and trap
representations made me somewhat paranoid about that matter.

There is also the fact that for the non-negative values of signed
types, the value bits in the corresponding unsigned type must be the
same. This, coupled with the fact that unsigned char is not padded, is
also enough to guarantee that an all zero bit representation must
represent the value 0 for all character types.
 
J

Jack Klein

Both versions may return NULL, which is not a pointer to an empty
string. Unless you expect the caller of your function to check for
NULL you should take appropriate action before returning p.

As for calloc: I always have a funny feeling about this "the space
is initialized to all bits zero" behaviour. That isn't a problem
when you're dealing with unsigned character entitities, but may have
"astonishing results" (to quote the C Rationale) when working with
other types. Thus I stay away from using it at all.

Sigh, here we go again:

Using calloc() to allocate memory, or using memset() to put zeros into
an array, is guaranteed to produce all 0 values for:

- signed char
- unsigned char
- plain char
- any exact-width types (i.e., uint32_t, etc.) provided in an
<stdint.h> header

....and in the real world...

- all integer types on all architectures in actual use today

What is not guaranteed is the effect on floating point types or
pointers.

--
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++ ftp://snurse-l.org/pub/acllc-c++/faq
 
I

Irrwahn Grausewitz

Sigh, here we go again:

Sorry for causing annoyance.
Using calloc() to allocate memory, or using memset() to put zeros into
an array, is guaranteed to produce all 0 values for:

- signed char
- unsigned char
- plain char
- any exact-width types (i.e., uint32_t, etc.) provided in an
<stdint.h> header

...and in the real world...

- all integer types on all architectures in actual use today

What is not guaranteed is the effect on floating point types or
pointers.

Copy, got it. <hummm-click>
Message printed and glued to my forehead. <fizzzz>
Thank you. <feeeeep>
Over and out. <twirrrrl> ;-)
 
D

Dan Pop

In said:
There is also the fact that for the non-negative values of signed
types, the value bits in the corresponding unsigned type must be the
same. This, coupled with the fact that unsigned char is not padded, is
also enough to guarantee that an all zero bit representation must
represent the value 0 for all character types.

And the answer to a defect report filed against C99 makes it clear that
an all zero bit representation must represent the value 0 for all
integer types. It's supposed to be part of TC2, when it will finally be
released.

Dan
 
D

Dan Pop

In said:
To make up a proper dynamically allocated empty C string, would it suffice to
say:

return calloc(1, 1);

or am I better off using the longer version

char *p = malloc(1);
if (p) *p = 0;
return p;

Since calloc() achieves exactly the same thing with less code, there is
no good reason for preferring the malloc version.

When I have dynamically allocate memory for a string that I'm building
myself, I use calloc, so that I don't have to bother writing the
terminating null character (it's very easy to forget it).

Dan
 
I

Irrwahn Grausewitz

(e-mail address removed) (Dan Pop) wrote:

And the answer to a defect report filed against C99 makes it clear that
an all zero bit representation must represent the value 0 for all
integer types.

That's a good thing to know; you are most certainly referring to DR263?
It's supposed to be part of TC2, when it will finally be
released.

Will TC2 be released in the near future?

(Sorry, if this OT for c.l.c)

TIA
Regards
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) wrote:



That's a good thing to know; you are most certainly referring to DR263?
Yup.


Will TC2 be released in the near future?

My crystal ball is out of repair, you'll have to ask in comp.std.c.

Dan
 
P

Peter Pichler

(regarding calloc vs malloc + clearing the memory manually)
Since calloc() achieves exactly the same thing with less code, there is
no good reason for preferring the malloc version.

Except when this would be the only calloc in the whole project. Not linking
in an extra function might save a few bytes of executable code. But then,
it might not. There is nothing in the standard to suggest one way or the
other, only my gut feeling.
 
R

rihad

When I have dynamically allocate memory for a string that I'm building
myself, I use calloc, so that I don't have to bother writing the
terminating null character (it's very easy to forget it).

Then you wish there were recalloc()? :)
 
D

Dan Pop

In said:
(regarding calloc vs malloc + clearing the memory manually)

Except when this would be the only calloc in the whole project. Not linking
in an extra function might save a few bytes of executable code. But then,
it might not. There is nothing in the standard to suggest one way or the
other, only my gut feeling.

Is saving a few bytes of executable code an overriding concern for you?

If yes, a more likely scenario is that malloc and calloc are part of the
same library module (and, therefore, get loaded together), but the user
code using malloc gets translated into more bytes of executable code ;-)

Dan
 
P

Peter Pichler

Dan Pop said:
In <[email protected]> "Peter Pichler"

Is saving a few bytes of executable code an overriding concern for you?

If yes, a more likely scenario is that malloc and calloc are part of the
same library module (and, therefore, get loaded together), but the user
code using malloc gets translated into more bytes of executable code ;-)

You are quite likely right in case of malloc vs. calloc. I know about at
least
one example when I replaced printf with my own version using putchar (I only
needed to print decimal numbers. By doing that, I saved 4 kB of compiled
executable, which was _huge_ for the target platform (Z180 with 32 kB of
EPROM).
 

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

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top