473,406 Members | 2,698 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,406 software developers and data experts.

malloc vs calloc

Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));
memset(&test, 0, sizeof(test));

/* code 2 */
struct sample test;
test = calloc(1, sizeof(struct sample));

Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.

Thanks
David
Nov 13 '05 #1
29 40330

"David Hill" <da***@wmol.com> wrote in message
news:GnEpb.74071$275.194415@attbi_s53...
Is there a difference between:


Troll. Didn't you just ask this?

Tom
Nov 13 '05 #2

On Tue, 4 Nov 2003, David Hill wrote:

Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));
Whoops! Corrected the obvious typos below:

/* code 1 */
struct sample *test;
test = malloc(sizeof *test);
memset(test, 0, sizeof *test);
/* code 2 */
struct sample *test;
test = calloc(1, sizeof *test);

Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.


OMMV, but I personally avoid 'calloc', along with some library
functions such as 'memmove', because I think their *exact* effects
are obscure, and I don't ever feel like reading manpages when I
don't have to.

In particular for your example, 'calloc' takes two arguments whose
order matters -- so I'd have to get that right, where with 'malloc'
I don't. Ease of use.

Secondly, 'calloc' tries to set all the newly allocated bytes to zero.
That generally takes O(n) time. Now C in general has a very close
correspondence between C-language statements and machine-level
instructions, and I feel that if I'm going to be performing a very
expensive setup step like "set this whole block to zero," that's
something that should *not* be hidden away inside a library function
call. The 'malloc'/'memset' idiom makes the cost of setting '*test'
to zero slightly more noticeable.

Those are the two big reasons I don't use 'calloc', but there's
one more: it is rarely the right tool for the job.

In fact, *neither* of those fragments is going to do what you want,
in the general case: setting a struct's bytes to all zero isn't the
same as setting each member of that struct to zero, especially when
it comes to pointers and floating-point numbers. There's no easy
way to set each member of a dynamically allocated 'struct' to zero,
though -- you have to do it one-by-one.

HTH,
-Arthur
Nov 13 '05 #3
"David Hill" <da***@wmol.com> writes:
Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));
`test' is not a pointer, so this assignment is invalid. I will
assume you meant to declare `test' as type `struct sample *'.

When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type. For instance,
*don't* write this:

int *x = malloc (sizeof (int) * 128); /* Don't do this! */

Instead, write it this way:

int *x = malloc (sizeof *x * 128);

There's a few reasons to do it this way:

* If you ever change the type that `x' points to, it's not
necessary to change the malloc() call as well.

This is more of a problem in a large program, but it's still
convenient in a small one.

* Taking the size of an object makes writing the statement
less error-prone. You can verify that the sizeof syntax is
correct without having to look at the declaration.
memset(&test, 0, sizeof(test));
`&test' would be correct if `test' didn't have a pointer type,
but since you meant it to have a pointer type (or why would you
assign it the result of malloc()) this should be changed to
memset(test, 0, sizeof *test);
/* code 2 */
struct sample test;
test = calloc(1, sizeof(struct sample));
Again, `test' needs to have a pointer type for this to be
reasonable.
Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.


The latter is more straightforward. It might even be faster if
the implementation has a source of pre-zeroed storage.

Often neither is portably correct, because pointer and
floating-point types, among others, need not have a null pointer
or zero value when set to all-bits-zero.
--
"I hope, some day, to learn to read.
It seems to be even harder than writing."
--Richard Heathfield
Nov 13 '05 #4
David Hill wrote:
Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));
memset(&test, 0, sizeof(test));
Well, the above is just plain wrong! ITYM:

struct sample * test;
test = malloc(sizeof *test);
if (test == NULL) {
/* take appropriate action */
}
memset(test, 0, sizeof *test);

/* code 2 */
struct sample test;
test = calloc(1, sizeof(struct sample));
Same problem. ITYM:

struct sample * test;
test = calloc(1, sizeof *test);
/* appropriate test for calloc failure */


Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.


Considering the fact that it's wrong [;-)], I doubt it.

Once corrected, however, they are equivalent.

HTH,
--ag

--
Artie Gold -- Austin, Texas
Oh, for the good old days of regular old SPAM.

Nov 13 '05 #5
On Mon, 3 Nov 2003 22:02:50 -0500 (EST), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote in comp.lang.c:

On Tue, 4 Nov 2003, David Hill wrote:

Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));
Whoops! Corrected the obvious typos below:

/* code 1 */
struct sample *test;
test = malloc(sizeof *test);
memset(test, 0, sizeof *test);
/* code 2 */
struct sample *test;
test = calloc(1, sizeof *test);

Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.


OMMV, but I personally avoid 'calloc', along with some library
functions such as 'memmove', because I think their *exact* effects
are obscure, and I don't ever feel like reading manpages when I
don't have to.


You think right about calloc(), wrong about memmove(). The effects of
the latter are perfectly defined.
In particular for your example, 'calloc' takes two arguments whose
order matters -- so I'd have to get that right, where with 'malloc'
I don't. Ease of use.


The order of the arguments to calloc() does NOT matter. Nor do the
exact values. ONLY the product of the two values matters.

--
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
Nov 13 '05 #6


Arthur J. O'Dwyer wrote:
On Tue, 4 Nov 2003, David Hill wrote:
Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));

Whoops! Corrected the obvious typos below:

/* code 1 */
struct sample *test;
test = malloc(sizeof *test);
memset(test, 0, sizeof *test);
/* code 2 */
struct sample *test;
test = calloc(1, sizeof *test);
Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.


.....snip........

In fact, *neither* of those fragments is going to do what you want,
in the general case: setting a struct's bytes to all zero isn't the
same as setting each member of that struct to zero, especially when
it comes to pointers and floating-point numbers. There's no easy
way to set each member of a dynamically allocated 'struct' to zero,
though -- you have to do it one-by-one.


You can assign a struct object the value of a static struct object.
I'm not sure if this is included in your reference of one-by-one.

#include <stdio.h>

struct test
{
int i;
double d;
int *ip;
} init;

int main(void)
{
struct test a = init;

printf("a.i = %d\na.d = %f\na.ip is%s a null pointer\n",
a.i,a.d,(a.ip==NULL)?"":" not");
return 0;
}

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

Nov 13 '05 #7

"David Hill" <da***@wmol.com> schrieb im Newsbeitrag
news:GnEpb.74071$275.194415@attbi_s53...
Is there a difference between:

/* code 1 */
struct sample test;
test = malloc(sizeof(struct sample));
memset(&test, 0, sizeof(test));

/* code 2 */
struct sample test;
test = calloc(1, sizeof(struct sample));

Why would code 1 be chosen over code 2? I tend to see many instances of
code 1 in source code and hardly any instances of code 2.


I think, zeroing a struct with either calloc() or malloc()/memset() is a Bad
Idea :). If you need just one struct, use

struct sample test = {0};

Which is guaranteed to fill all the members with the appropriate zero values
(NULL for pointers, 0.0 for floating point values etc).
And if you have to malloc() an array of structs and zero them it's better to
write something like
(snippet only, headers, #defines etc omitted)

size_t i;
struct sample empty = {0};
struct sample *test = malloc(NUMBER_OF_STRUCTS_WANTED * sizeof *test);
if(test)
{
for(i = 0; i < NUMBER_OF_STRUCTS_WANTED; i++)
{
test[i] = empty;
}
/*do something with test*/
free(test);
}

Using an initializer gives you also the possibility to initialize your
structs to non-zero values:

struct tag_test
{
size_t size;
int available;
char some_text[SOME_SIZE];
}init_struct = {sizeof init_struct, 1, "Item"};
Robert
Nov 13 '05 #8
"Tom St Denis" <to********@iahu.ca> wrote:
"David Hill" <da***@wmol.com> wrote:
Is there a difference between:
Troll.


I don't think so.
Didn't you just ask this?


No, he didn't. It was somebody else:

# From: rihad <ri***@mail.ru>
# Newsgroups: comp.lang.c
# Subject: calloc(1,1) vs. *malloc(1)=0
# Date: Thu, 30 Oct 2003 00:12:16 +0400
# Message-ID: <ai********************************@4ax.com>

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #9
In <Pi***********************************@unix41.andr ew.cmu.edu> "Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:

In particular for your example, 'calloc' takes two arguments whose
order matters -- so I'd have to get that right, where with 'malloc'
I don't.
Please elaborate. What happens if you get the calloc argument order
"wrong"?
Secondly, 'calloc' tries to set all the newly allocated bytes to zero.
That generally takes O(n) time. Now C in general has a very close
correspondence between C-language statements and machine-level
instructions, and I feel that if I'm going to be performing a very
expensive setup step like "set this whole block to zero," that's
something that should *not* be hidden away inside a library function
call. The 'malloc'/'memset' idiom makes the cost of setting '*test'
to zero slightly more noticeable.
Isn't it still hidden away inside a library function call?
Those are the two big reasons I don't use 'calloc', but there's
one more: it is rarely the right tool for the job.


It's not that exotic to initialise an object to all zeroes at the very
point you bring it into existence. calloc can achieve this for quite a
wide range of objects (only floating point and pointers can't be
*portably* set to zero this way, but, if your code is already
non-portable, this is the least of your worries: conforming
implementations where all bits zero don't work as expected for floating
point and pointers are few and far between).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #10


Dan Pop wrote:
In <Pi***********************************@unix41.andr ew.cmu.edu> "Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
In particular for your example, 'calloc' takes two arguments whose
order matters -- so I'd have to get that right, where with 'malloc'
I don't.

Please elaborate. What happens if you get the calloc argument order
"wrong"?


The Standard defines what occurs if the argument order is not "wrong".
What does the Standard state should you reverse this order?

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

Nov 13 '05 #11
On Tue, 04 Nov 2003 10:11:47 -0500
Al Bowers <xa******@rapidsys.com> wrote:
Dan Pop wrote:
In <Pi***********************************@unix41.andr ew.cmu.edu>
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
In particular for your example, 'calloc' takes two arguments whose
order matters -- so I'd have to get that right, where with 'malloc'
I don't.


Please elaborate. What happens if you get the calloc argument order
"wrong"?


The Standard defines what occurs if the argument order is not "wrong".
What does the Standard state should you reverse this order?


Instead of enough space for 100 elements 10 bytes long you will get
enough space for 10 elements 100 bytes long, for example. Fortunately
(or deliberately) both parameters to calloc are of type size_t, so
swapping them won't cause overflow problems, and last I checked x*y==y*x
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.
Nov 13 '05 #12
In <bo*************@ID-169908.news.uni-berlin.de> Al Bowers <xa******@rapidsys.com> writes:


Dan Pop wrote:
In <Pi***********************************@unix41.andr ew.cmu.edu> "Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
In particular for your example, 'calloc' takes two arguments whose
order matters -- so I'd have to get that right, where with 'malloc'
I don't.

Please elaborate. What happens if you get the calloc argument order
"wrong"?


The Standard defines what occurs if the argument order is not "wrong".
What does the Standard state should you reverse this order?


The obvious: that, instead of allocating space for N objects of M bytes
each, you allocate memory for M objects of N bytes each. That is
assuming that the "right" calloc call was calloc(N, M).

Now, pray tell, what is the difference between the two scenarios,
considering the general properties of malloc and friends?

If I want to allocate space for a string of 9 characters, which is the
"right" calloc call (calloc(1, 10) or calloc(10, 1)) and why?

Trivia quizz, for the beginner: there is a similar issue with the second
and third arguments of a fread or fwrite call, but there it does make a
real difference. Explain the difference between fread(buf, 1, 10, fp)
and fread(buf, 10, 1, fp).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #13


Dan Pop wrote:
In <bo*************@ID-169908.news.uni-berlin.de> Al Bowers <xa******@rapidsys.com> writes:
Dan Pop wrote:
Please elaborate. What happens if you get the calloc argument order
"wrong"?


The Standard defines what occurs if the argument order is not "wrong".
What does the Standard state should you reverse this order?

The obvious: that, instead of allocating space for N objects of M bytes
each, you allocate memory for M objects of N bytes each. That is
assuming that the "right" calloc call was calloc(N, M).


The Standard states that? Chapter and verse please!

Or is this your obvious conclusion?
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 13 '05 #14
"Dan Pop" <Da*****@cern.ch> wrote:
Trivia quizz, for the beginner: there is a similar issue with the second
and third arguments of a fread or fwrite call, but there it does make a
real difference. Explain the difference between fread(buf, 1, 10, fp)
and fread(buf, 10, 1, fp).


The only difference, in my experience, is in the integer value returned
from the fread function when it succeeds -- the former would return 10,
the latter would return 1.

I suppose if a read error or EOF occurred partway through the read,
the former fread call would give you more idea of exactly how much
data actually got read rather than the latter's simple yes/no reply.

--
Simon.
Nov 13 '05 #15

On Tue, 4 Nov 2003, Al Bowers wrote:

Dan Pop wrote:
Al Bowers <xa******@rapidsys.com> writes:
Dan Pop wrote: [re my first reason why I avoid calloc]Please elaborate. What happens if you get the calloc argument order
"wrong"?

The Standard defines what occurs if the argument order is not "wrong".
What does the Standard state should you reverse this order?


The obvious: that, instead of allocating space for N objects of M bytes
each, you allocate memory for M objects of N bytes each. That is
assuming that the "right" calloc call was calloc(N, M).


The Standard states that? Chapter and verse please!

Or is this your obvious conclusion?


For the record, I am almost positive that Dan Pop is exactly
right; getting calloc's arguments in the wrong order has absolutely
no ill effects. However, I see that some people *aren't* positively
of that opinion, and will demand proof of correctness.
Quod erat demonstrandum: it's easier to use malloc and avoid
the pedantic arguments, than use calloc and risk having to debate
obscure little points of the Standard. :-)

OTOH, Dan, if the argument order really *doesn't* matter, then
why does the Standard bother to specify which parameter is
which? [And why have 'calloc' take two arguments to begin with,
if it's *only* their product which matters? [Historical reasons.
But I'm interested to see what you'll say for the first question.]]

-Arthur
Nov 13 '05 #16
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> scribbled the following:
On Tue, 4 Nov 2003, Al Bowers wrote:
Dan Pop wrote:
> Al Bowers <xa******@rapidsys.com> writes:
>>Dan Pop wrote: [re my first reason why I avoid calloc] >>>Please elaborate. What happens if you get the calloc argument order
>>>"wrong"?
>>
>>The Standard defines what occurs if the argument order is not "wrong".
>>What does the Standard state should you reverse this order?
>
> The obvious: that, instead of allocating space for N objects of M bytes
> each, you allocate memory for M objects of N bytes each. That is
> assuming that the "right" calloc call was calloc(N, M).
The Standard states that? Chapter and verse please!

Or is this your obvious conclusion?

For the record, I am almost positive that Dan Pop is exactly
right; getting calloc's arguments in the wrong order has absolutely
no ill effects. However, I see that some people *aren't* positively
of that opinion, and will demand proof of correctness.
Quod erat demonstrandum: it's easier to use malloc and avoid
the pedantic arguments, than use calloc and risk having to debate
obscure little points of the Standard. :-)
I am of the opinion that Dan Pop is completely correct. The effects of
reversing the order of calloc()'s parameters is nothing. Zippo. Nada.
Zilch. The fat lady has sung.
OTOH, Dan, if the argument order really *doesn't* matter, then
why does the Standard bother to specify which parameter is
which? [And why have 'calloc' take two arguments to begin with,
if it's *only* their product which matters? [Historical reasons.
But I'm interested to see what you'll say for the first question.]]


Which historical reasons would those be? Was there really a time when
it mattered, or was it just aesthetics? A remnant of B, BCPL, or an
even earlier language?
And as I've myself asked before, what's the point in gets() existing
in the first place?

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Last year he disrespected me - and then he showed lack of respect."
- Anthony Mason
Nov 13 '05 #17
Al Bowers wrote:

Dan Pop wrote:
In <bo*************@ID-169908.news.uni-berlin.de> Al Bowers <xa******@rapidsys.com> writes:
Dan Pop wrote:Please elaborate. What happens if you get the calloc argument order
"wrong"?
The Standard defines what occurs if the argument order is not "wrong".
What does the Standard state should you reverse this order?

The obvious: that,
instead of allocating space for N objects of M bytes
each, you allocate memory for M objects of N bytes each. That is
assuming that the "right" calloc call was calloc(N, M).


The Standard states that? Chapter and verse please!


My understanding of this part of the standard,
agrees with Dan Pop.

N869
7.20.3.1 The calloc function
Synopsis
[#1]
#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
Description
[#2] The calloc function allocates space for an array of
nmemb objects, each of whose size is size.
Nov 13 '05 #18
On Tue, 4 Nov 2003 15:27:31 -0500 (EST), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote:
OTOH, Dan, if the argument order really *doesn't* matter, then
why does the Standard bother to specify which parameter is
which?


That's easy: because it's simpler than explaining that it doesn't
matter.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 13 '05 #19
On 4 Nov 2003 21:10:26 GMT, Joona I Palaste <pa*****@cc.helsinki.fi>
wrote:
which? [And why have 'calloc' take two arguments to begin with,
if it's *only* their product which matters? [Historical reasons.
But I'm interested to see what you'll say for the first question.]]


Which historical reasons would those be? Was there really a time when
it mattered, or was it just aesthetics? A remnant of B, BCPL, or an
even earlier language?


I dunno about history, but it's a documentation aid - emphasizing that
you're asking for N spaces for an object of some certain size. Also
useful, since when calculating space requirements,most likely what you
want is N objects of type struct foo.

Now, the question is why doesn't malloc take two parameters?

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 13 '05 #20

On Tue, 4 Nov 2003, Joona I Palaste wrote:

Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> scribbled the following:

OTOH, Dan, if the argument order really *doesn't* matter, then
why does the Standard bother to specify which parameter is
which? [And why have 'calloc' take two arguments to begin with,
if it's *only* their product which matters? [Historical reasons.
But I'm interested to see what you'll say for the first question.]]
Which historical reasons would those be?


That by the time C was being standardized, 'calloc' had already
been defined for more than 10 years as taking two arguments. (My
copy of K&R1 is back! ;-)
Incidentally, K&R1 describes 'calloc' as returning a block of
memory sized "for n objects of the specified size" and suitably
aligned "for the object in question." Thus, it's conceivable
that certain pre-standard implementations might have been
optimized to return less-strictly-aligned pointers from

calloc(1024, sizeof(char))

than from

calloc(1, sizeof(my_1024_byte_object))

--hence the pair of arguments. But I have no hard evidence
to support such a conclusion.

And as I've myself asked before, what's the point in gets()
existing in the first place?


Same reason -- it was used in a lot of existing code, and the
standards committee didn't want to break that code. Sure, it
was a dumb function to create in the *very* first place, but
it probably got entrenched before anyone noticed how awful it
really could be. And by the time it was mentioned in K&R, there
was no way anyone was going to be able to displace it.

-Arthur

Nov 13 '05 #21
On Tue, 4 Nov 2003 15:27:31 -0500 (EST), in comp.lang.c , "Arthur J.
O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
For the record, I am almost positive that Dan Pop is exactly
right; getting calloc's arguments in the wrong order has absolutely
no ill effects.


I tend to agree. However, out of interest, what if the platform wanted
a specific alignment, or if there were padding after a structure's
last member?

Is it not the case that calloc (8, 7) might create eight 7 byte
objects aligned to 8 byte boundaries, while calloc(7,8) might create
seven 8 byte objects similarly aligned. The former block would then be
larger than the latter possibly?

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 13 '05 #22
Mark McIntyre wrote:

On Tue, 4 Nov 2003 15:27:31 -0500 (EST), in comp.lang.c , "Arthur J.
O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
For the record, I am almost positive that Dan Pop is exactly
right; getting calloc's arguments in the wrong order has absolutely
no ill effects.


I tend to agree. However, out of interest, what if the platform wanted
a specific alignment, or if there were padding after a structure's
last member?

Is it not the case that calloc (8, 7) might create eight 7 byte
objects aligned to 8 byte boundaries, while calloc(7,8) might create
seven 8 byte objects similarly aligned. The former block would then be
larger than the latter possibly?


calloc is creating memory for an array.
There's no padding between elements in an array.

7.20.3 Memory management functions
[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated).
Nov 13 '05 #23
In article <Pi**********************************@unix47.andre w.cmu.edu>
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> writes:
Incidentally, K&R1 describes 'calloc' as returning a block of
memory sized "for n objects of the specified size" and suitably
aligned "for the object in question." Thus, it's conceivable
that certain pre-standard implementations might have been
optimized to return less-strictly-aligned pointers from

calloc(1024, sizeof(char))

than from

calloc(1, sizeof(my_1024_byte_object))

--hence the pair of arguments. But I have no hard evidence
to support such a conclusion.


As further evidence that this was at least in the mind of whoever
wrote calloc(), in the ancient Unix C libraries (Phototypesetter
V6, maybe earlier?) one was *supposed* to free calloc()ed memory
with the companion function cfree(). But many programs just called
free() anyway -- which worked because the actual implementation of
calloc() just called malloc() -- and I imagine the idea of a separate
allocator was abandoned.

A number of the oddities and excrescences in both C and Unix are
there simply because a bad idea got entrenched. Which, interestingly,
relates to the discussion (if one can call it that) going on
elsethread, about whether to write portable code or "just get the
job done at the moment" code and worry about portability later.
It is true that "get the job done any dirty, hacky ol' way" *can*
improve one's time-to-market, which some -- perhaps too many --
companies believe is paramount, far more important than any kind
of reliability or maintainability. They may even be right (which
would explain the sad state of so much software). Yet, paradoxically,
writing portable code in the first place can *also* improve one's
time-to-market. A great deal depends on the situation, and situations
have a way of changing unexpectedly.

(My personal preference is to write code that is "as portable as
seems possible and cost-effective" from the start, so that it has
a good chance of porting when the situation does change. I think
that the time required to learn what it takes to achieve this is
well-spent. But others -- even some I consider reasonable people
-- do disagree at times. :-) )
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://67.40.109.61/torek/index.html (for the moment)
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 13 '05 #24
In <Pi**********************************@unix47.andre w.cmu.edu> "Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:

On Tue, 4 Nov 2003, Joona I Palaste wrote:

Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> scribbled the following:
>
> OTOH, Dan, if the argument order really *doesn't* matter, then
> why does the Standard bother to specify which parameter is
> which? [And why have 'calloc' take two arguments to begin with,
> if it's *only* their product which matters? [Historical reasons.
> But I'm interested to see what you'll say for the first question.]]


Which historical reasons would those be?


That by the time C was being standardized, 'calloc' had already
been defined for more than 10 years as taking two arguments. (My
copy of K&R1 is back! ;-)
Incidentally, K&R1 describes 'calloc' as returning a block of
memory sized "for n objects of the specified size" and suitably
aligned "for the object in question." Thus, it's conceivable
that certain pre-standard implementations might have been
optimized to return less-strictly-aligned pointers from

calloc(1024, sizeof(char))

than from

calloc(1, sizeof(my_1024_byte_object))

--hence the pair of arguments. But I have no hard evidence
to support such a conclusion.


Nevertheless, your analysis makes sense.
And as I've myself asked before, what's the point in gets()
existing in the first place?


Same reason -- it was used in a lot of existing code, and the
standards committee didn't want to break that code. Sure, it
was a dumb function to create in the *very* first place, but
it probably got entrenched before anyone noticed how awful it
really could be. And by the time it was mentioned in K&R, there
was no way anyone was going to be able to displace it.


This still doesn't explain why C89 (or even C99) didn't deprecate it.

BTW, the C standard library doesn't contain any properly designed function
for reading a line of input from a text stream. As a result, many
programmers invent their own wheel, which is downright silly. fgets()
is safe but it is also a pain in the ass to use correctly.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #25


Dan Pop wrote:
In <bo*************@ID-169908.news.uni-berlin.de> Al Bowers <xa******@rapidsys.com> writes:
If I want to allocate space for a string of 9 characters, which is the
"right" calloc call (calloc(1, 10) or calloc(10, 1)) and why?


How can you construct a "right" way?
One visualizes the allocation as an object of 1 string of 9 characters.
Thus:
calloc(1,10);

or One visualize the allocation 1 string of 9 characters as a allocation
of an array of 10 characters. Thus:
calloc(10,1);
Either way, the allocation is the same.

Consider a more complex example; an allocation of an array of a struct
type. Using the standard as as guide, the first argument would be the
nember of structs in the array and the second argument would be the
size of the struct. If one is haphazard in the order of the arguments,
the allocation would be the same, however, I would consider it sloppy
code, which may lead to code management confusion.

This code seq faults. Why?
I see, variable b, the first argument in calloc, does not
represent the numb of structs in the array.

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

#define STRUCT_NR 7

struct test
{
char name[80];
char addr[80];
} init = {{"NAME GOES HERE"},{"ADDRESS GOES HERE"}};

int main(void)
{
size_t a = STRUCT_NR, b = sizeof(struct test),i;
struct test *s;

if((s = calloc(b,a)) == NULL) return EXIT_FAILURE;
/* Ok, calloc 1st argument, b, should represent num. structs*/
for(i = 0; i < b;i++) s[i] = init;
printf("s[0].name is %s\ns[0].addr is %s\n", s[0].name,s[0].addr);
return 0;
}

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

Nov 13 '05 #26
In <bo*************@ID-169908.news.uni-berlin.de> Al Bowers <xa******@rapidsys.com> writes:


Dan Pop wrote:
In <bo*************@ID-169908.news.uni-berlin.de> Al Bowers <xa******@rapidsys.com> writes:
If I want to allocate space for a string of 9 characters, which is the
"right" calloc call (calloc(1, 10) or calloc(10, 1)) and why?


How can you construct a "right" way?
One visualizes the allocation as an object of 1 string of 9 characters.
Thus:
calloc(1,10);

or One visualize the allocation 1 string of 9 characters as a allocation
of an array of 10 characters. Thus:
calloc(10,1);
Either way, the allocation is the same.


You have to ask this question to the poster who thought that there is
a right way and a wrong way of specifying calloc's arguments. I didn't
put the word right between double quotes just because I cannot control
my fingers while typing ;-)
Consider a more complex example; an allocation of an array of a struct
type. Using the standard as as guide, the first argument would be the
nember of structs in the array and the second argument would be the
size of the struct. If one is haphazard in the order of the arguments,
the allocation would be the same, however, I would consider it sloppy
code, which may lead to code management confusion.
Which has exactly nothing to do with the program's correctness, from the
standard's point of view.
This code seq faults. Why?
I see, variable b, the first argument in calloc, does not
represent the numb of structs in the array.

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

#define STRUCT_NR 7

struct test
{
char name[80];
char addr[80];
} init = {{"NAME GOES HERE"},{"ADDRESS GOES HERE"}};

int main(void)
{
size_t a = STRUCT_NR, b = sizeof(struct test),i;
struct test *s;

if((s = calloc(b,a)) == NULL) return EXIT_FAILURE;
/* Ok, calloc 1st argument, b, should represent num. structs*/
for(i = 0; i < b;i++) s[i] = init;
printf("s[0].name is %s\ns[0].addr is %s\n", s[0].name,s[0].addr);
return 0;
}


The bug is NOT in the calloc() call. I entirely agree that calling
calloc according to its description has a great impact on program's
readability/maintenability, but this is NOT a correctness issue. The
code is *always* correct if the programmer is consistent in his usage
of the two arguments of calloc(), even if his usage is not the one
described in the standard.

In your example, if you used meaningful names for a and b, like nelem and
size, the bug would have been immediately obvious, despite the unorthodox
calloc call. It is your silly naming choice that obfuscates the bug: one
shouldn't derive the meaning of a variable from its position in a calloc
call.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #27
In <3f**********************@news.optusnet.com.au> "Simon Biber" <ne**@ralminNOSPAM.cc> writes:
"Dan Pop" <Da*****@cern.ch> wrote:
Trivia quizz, for the beginner: there is a similar issue with the second ^^^^^^^^^^^^^^^^ and third arguments of a fread or fwrite call, but there it does make a
real difference. Explain the difference between fread(buf, 1, 10, fp)
and fread(buf, 10, 1, fp).


The only difference, in my experience, is in the integer value returned
from the fread function when it succeeds -- the former would return 10,
the latter would return 1.

I suppose if a read error or EOF occurred partway through the read,
the former fread call would give you more idea of exactly how much
data actually got read rather than the latter's simple yes/no reply.


Any time I post a trivia quizz for the beginners, one of the regulars
feels compelled to spoil it...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #28
Dan Pop wrote:
In <3f**********************@news.optusnet.com.au> "Simon Biber"
<ne**@ralminNOSPAM.cc> writes:
I suppose if a read error or EOF occurred partway through the read,
the former fread call would give you more idea of exactly how much
data actually got read rather than the latter's simple yes/no reply.


Any time I post a trivia quizz for the beginners, one of the regulars
feels compelled to spoil it...


....and then some other regular adds to your misery by maliciously correcting
your misspelling of "quiz". Life's a bitch, isn't it? :-)

Oh, I nearly forgot. All spelling flames must contain a spelling error, so
here's min.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #29
Dan Pop <Da*****@cern.ch> wrote:
In <3f**********************@news.optusnet.com.au> "Simon Biber" <ne**@ralminNOSPAM.cc> writes:
"Dan Pop" <Da*****@cern.ch> wrote:
Trivia quizz, for the beginner: there is a similar issue with the second ^^^^^^^^^^^^^^^^ and third arguments of a fread or fwrite call, but there it does make a
real difference. Explain the difference between fread(buf, 1, 10, fp)
and fread(buf, 10, 1, fp).


The only difference, in my experience, is in the integer value returned
from the fread function when it succeeds -- the former would return 10,
the latter would return 1.

I suppose if a read error or EOF occurred partway through the read,
the former fread call would give you more idea of exactly how much
data actually got read rather than the latter's simple yes/no reply.

Any time I post a trivia quizz for the beginners, one of the regulars
feels compelled to spoil it...


Maybe because they fail to see the connection between this mysterious
"quizz" thing and a "quiz" :-)

Alex
Nov 13 '05 #30

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

Similar topics

17
by: rihad | last post by:
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;...
14
by: Rahul Gandhi | last post by:
Which one is more fast? malloc followed by memset or calloc
27
by: MK | last post by:
I am a newbie. Please help. The following warning is issued by gcc-3.2.2 compiler (pc Linux): ================================================================== read_raw_data.c:51: warning:...
37
by: Harsimran | last post by:
Can any one explain what are far pointers and what is the difference between malloc and calloc .Which is better ?
11
by: lohith.matad | last post by:
Hi all, Though the purpose of both malloc() and calloc() is the same, and as we also know that calloc() initializes the alloacted locations to 'zero', and also that malloc() is used for bytes...
8
by: venkatesh | last post by:
hai to everybody, i am having doubt in difference between the malloc and calloc function. please tell where to use and when to use those functions?
14
by: Roka100 | last post by:
Hi all, I tried 2 programs : #include <stdio.h> #include <string.h> 1, int main(void){ char *str = NULL;
318
by: jacob navia | last post by:
Rcently I posted code in this group, to help a user that asked to know how he could find out the size of a block allocated with malloc. As always when I post something, the same group of people...
46
by: lovecreatesbea... | last post by:
Do you prefer malloc or calloc? p = malloc(size); Which of the following two is right to get same storage same as the above call? p = calloc(1, size); p = calloc(size, 1);
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
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,...
0
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...
0
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.