There's no difference in the size of the memory block
allocated. calloc
just fills the memory block with physical
all-zero-bits pattern. In practice it is often assumed that the objects located in the
memory block allocated with calloc
have initilial value as if
they were initialized with literal 0
, i.e. integers should have
value of 0
, floating-point variables - value of
0.0
, pointers - the appropriate null-pointer value, and so
on.
From the pedantic point of view though,
calloc
(as well as memset(..., 0,
) is only guaranteed to properly initialize (with zeroes) objects of
...)
type unsigned char
. Everything else is not guaranteed to be
properly initialized and may contain so called trap representation,
which causes undefined behavior. In other words, for any type other than
unsigned char
the aforementioned all-zero-bits patterm might
represent an illegal value, trap representation.
Later, in
one of the Technical Corrigenda to C99 standard, the behavior was defined for all
integer types (which makes sense). I.e. formally, in the current C language you can
initialize only integer types with calloc
(and
memset(..., 0, ...)
). Using it to initialize anything else in
general case leads to undefined behavior, from the point of view of C
language.
In practice, calloc
works, as we all know :), but whether you'd want to use it (considering the above) is up
to you. I personally prefer to avoid it completely, use malloc
instead and perform my own initialization.
Finally, another
important detail is that calloc
is required to calculate the
final block size internally, by multiplying element size by number
of elements. While doing that, calloc
must watch for possible
arithmetic overflow. It will result in unsuccessful allocation (null pointer) if the
requested block size cannot be correctly calculated. Meanwhile, your
malloc
version makes no attempt to watch for overflow. It will
allocate some "unpredictable" amount of memory in case overflow
happens.
No comments:
Post a Comment