By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,505 Members | 1,761 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,505 IT Pros & Developers. It's quick & easy.

difference between malloc and calloc?

P: n/a
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?

Nov 19 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
venkatesh <pv***********@gmail.com> schrieb:
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?


malloc takes one parameter (number of chars to allocate) and
does not initialize the allocated memory, whereas calloc takes
two parameters (number of elements and number of chars per
element) and initialises the allocated memory to zero.

Examples:

// This allocats 500 ints, it does not initialize the memory:
int *m = malloc(500*sizeof(int));

// This, too, allocates 500 ints, but initializes the memory
// to zero:
int *c = calloc(500,sizeof(int));

hth.

Markus
Nov 19 '05 #2

P: n/a
venkatesh wrote:
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?


Markus Becker has explained the difference. The second
part of your question is about which function to use under
what circumstances, and my suggestion is "Use malloc() almost
always and calloc() almost never."

The reason is that the initialization to zero that calloc()
performs is usually not very helpful:

- The initialization to "all-bits-zero" is not necessarily
the same as initialization to "all-data-zero." C says
very little about the representation of values in memory,
nothing at all for floating-point or pointer values. On
many machines all-bits-zero representations will in fact
correspond to f.p. zeroes or null pointers, but this is
not guaranteed by the language and there have been machines
where the correspondence did not hold. If you get in the
habit of using calloc() to initialize f.p. and pointer
items, you may be heading for trouble.

- Usually, one allocates a chunk of dynamic memory in order
to store something in it -- and when you store something
in it, you'll overwrite whatever was there before. Thus,
the initialization performed by calloc() is usually not
needed anyhow. There are occasional exceptions where all-
bits-zero initialization is helpful, but they are unusual.
Not unheard-of, I grant, but unusual.

There's one possible advantage I can imagine for calloc() over
malloc(), and that's the opportunity for a tiny bit of sanity-
checking. Here are two ways you might try to allocate memory to
hold N items of SomeType:

SomeType *p = malloc(N * sizeof *p);
SomeType *q = calloc(N, sizeof *q);

Now, if N is so large that multiplying it by sizeof(SomeType)
exceeds the valid range of size_t, the argument in the first
form will "wrap around" and you'll silently request less memory
than you wanted; if the request succeeds you'll proceed merrily
along and try to store N items in too small a space, with the
usually unhappy and sometimes baffling consequences. The second
form, however, will fail and return NULL so your program will be
alerted that the space was not available; there'll be no silent
error. However, this seems to me to be a very small advantage,
so I'll stick with my original suggestion: malloc() almost always,
calloc() almost never.

--
Eric Sosman
es*****@acm-dot-org.invalid

Nov 19 '05 #3

P: n/a
Eric Sosman wrote:
There's one possible advantage I can imagine for calloc() over
malloc(), and that's the opportunity for a tiny bit of sanity-
checking. Here are two ways you might try to allocate memory to
hold N items of SomeType:

SomeType *p = malloc(N * sizeof *p);
SomeType *q = calloc(N, sizeof *q);

Now, if N is so large that multiplying it by sizeof(SomeType)
exceeds the valid range of size_t, the argument in the first
form will "wrap around" and you'll silently request less memory
than you wanted; if the request succeeds you'll proceed merrily
along and try to store N items in too small a space, with the
usually unhappy and sometimes baffling consequences. The second
form, however, will fail and return NULL so your program will be
alerted that the space was not available; there'll be no silent
error. However, this seems to me to be a very small advantage,
so I'll stick with my original suggestion: malloc() almost always,
calloc() almost never.


Does this mean that

void *my_calloc1(size_t a, size_t b)
{
void *p = malloc(a * b);
if(p) memset(p, 0, a * b);
return p;
}

would not be a valid implementation of calloc, because of the
possibility of overflow?

If calloc needs to check for overflow in a * b, how should it do so?

void *my_calloc2(size_t a, size_t b)
{
void *p = NULL;
size_t n = a * b;
if(a && b && n / a == b && n / b == a)
{
p = malloc(n);
if(p) memset(p, 0, n);
}
return p;
}

Perhaps this is overkill...

--
Simon.
Nov 19 '05 #4

P: n/a
Simon Biber wrote:

Eric Sosman wrote:
There's one possible advantage I can imagine for calloc() over
malloc(), and that's the opportunity for a tiny bit of sanity-
checking. Here are two ways you might try to allocate memory to
hold N items of SomeType:

SomeType *p = malloc(N * sizeof *p);
SomeType *q = calloc(N, sizeof *q);

Now, if N is so large that multiplying it by sizeof(SomeType)
exceeds the valid range of size_t, the argument in the first
form will "wrap around" and you'll silently request less memory
than you wanted; if the request succeeds you'll proceed merrily
along and try to store N items in too small a space, with the
usually unhappy and sometimes baffling consequences. The second
form, however, will fail and return NULL so your program will be
alerted that the space was not available; there'll be no silent
error. However, this seems to me to be a very small advantage,
so I'll stick with my original suggestion: malloc() almost always,
calloc() almost never.
Does this mean that

void *my_calloc1(size_t a, size_t b)
{
void *p = malloc(a * b);
if(p) memset(p, 0, a * b);
return p;
}

would not be a valid implementation of calloc, because of the
possibility of overflow?


I don't know.
If calloc needs to check for overflow in a * b, how should it do so?

void *my_calloc2(size_t a, size_t b)
{
void *p = NULL;
size_t n = a * b;
if(a && b && n / a == b && n / b == a)
{
p = malloc(n);
if(p) memset(p, 0, n);
}
return p;
}

Perhaps this is overkill...


I think calloc(0) should return the same value as malloc(0),
whatever that may be.

And I think that only one of these checks is needed:
n / a == b && n / b == a

void *my_calloc3(size_t a, size_t b)
{
void *p;
size_t n;

if (a == 0 || b == 0) {
p = malloc(0);
} else {
n = a * b;
if (n / a == b) {
p = malloc(n);
if (p != NULL) {
memset(p, 0, n);
}
} else {
p = NULL;
}
}
return p;
}

--
pete
Nov 20 '05 #5

P: n/a
Simon Biber wrote:
Eric Sosman wrote:
There's one possible advantage I can imagine for calloc() over
malloc(), and that's the opportunity for a tiny bit of sanity-
checking. Here are two ways you might try to allocate memory to
hold N items of SomeType:

SomeType *p = malloc(N * sizeof *p);
SomeType *q = calloc(N, sizeof *q);

Now, if N is so large that multiplying it by sizeof(SomeType)
exceeds the valid range of size_t, the argument in the first
form will "wrap around" and you'll silently request less memory
than you wanted; if the request succeeds you'll proceed merrily
along and try to store N items in too small a space, with the
usually unhappy and sometimes baffling consequences. The second
form, however, will fail and return NULL so your program will be
alerted that the space was not available; there'll be no silent
error. However, this seems to me to be a very small advantage,
so I'll stick with my original suggestion: malloc() almost always,
calloc() almost never.

Does this mean that

void *my_calloc1(size_t a, size_t b)
{
void *p = malloc(a * b);
if(p) memset(p, 0, a * b);
return p;
}

would not be a valid implementation of calloc, because of the
possibility of overflow?


Yes, I think it would be invalid. The Standard says (in
7.20.3.1)

The calloc function allocates space for an array of
/nmemb/ objects, each of whose size is /size/. [...]

This is subject to the general condition in 7.20.3

[...] If the space cannot be allocated, a null pointer
is returned. [...]

Thus, if calloc() cannot find sufficient space for /nmemb/
objects of /size/ bytes each, it must return NULL. There is no
special dispensation for overflow of nmemb * size; there is just
the requirement for a NULL returned value.
If calloc needs to check for overflow in a * b, how should it do so?


The response by "pete" seems to cover what's needed.

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 20 '05 #6

P: n/a
pete wrote:

void *my_calloc3(size_t a, size_t b)
{
void *p;
size_t n;

if (a == 0 || b == 0) {
p = malloc(0);
} else {
n = a * b;
if (n / a == b) {
To be pedantic, size_t may theoretically promote to int, which can
overflow.

if (a <= ((size_t) -1) / b) {
n = a * b;
p = malloc(n);
if (p != NULL) {
memset(p, 0, n);
}
} else {
p = NULL;
}
}
return p;
}


--
Peter

Nov 20 '05 #7

P: n/a
On 2005-11-20, Peter Nilsson <ai***@acay.com.au> wrote:
pete wrote:

void *my_calloc3(size_t a, size_t b)
{
void *p;
size_t n;

if (a == 0 || b == 0) {
p = malloc(0);
} else {
n = a * b;
if (n / a == b) {


To be pedantic, size_t may theoretically promote to int, which can
overflow.


Eh? If size_t can promote to int, how can it overflow it?
Nov 20 '05 #8

P: n/a
Jordan Abel wrote:

On 2005-11-20, Peter Nilsson <ai***@acay.com.au> wrote:
pete wrote:

void *my_calloc3(size_t a, size_t b)
{
void *p;
size_t n;

if (a == 0 || b == 0) {
p = malloc(0);
} else {
n = a * b;
if (n / a == b) {


To be pedantic, size_t may theoretically promote to int, which can
overflow.


Eh? If size_t can promote to int, how can it overflow it?


I suppose if 'a' was lower ranking than int,
like unsigned short or unsigned char,
and the max value for that type was equal to INT_MAX,
and 'a' was equal to INT_MAX and 'b' was greater than 1,
or any other combination where the product of a*b exceded INT_MAX,
then a*b would overflow.

If a byte has enough bits to represent all the positive
values within the range of int,
then an allowable way to implement an int,
is to make sizeof(int) equal to 2,
and use the high order byte just for the sign bit.

I never heard of a size_t lower ranking than unsigned.
It would be strange, but I think it's allowed.

--
pete
Nov 20 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.