views:

378

answers:

3

I am following this tutorial (http://theocacao.com/document.page/234). I am confused about this paragraph, mainly the lines relating to calloc:

We can also use a variation of the malloc function, called calloc. The calloc function takes two arguments, a value count and the base value size. It also clears the memory before returning a pointer, which is useful in avoiding unpredictable behavior and crashes in certain cases:

That last line confuses me. What does it mean to clear the memory?

+9  A: 

The function calloc will ensure all bytes in the memory returned are set to 0. malloc makes no such guarantees. The data it returns can, and will, consist of seemingly random data.

The distinction is very useful for initialization of data members. If 0 is a good default for all values in a struct then calloc can simplify struct creation.

Foo* pFoo = calloc(1, sizeof(Foo));

vs.

Foo* pFoo = malloc(sizeof(Foo));
pFoo->Value1 = 0;
pFoo->Value2 = 0;

Null checking omitted for clarity.

JaredPar
...with the consequence that if *you* don't properly initialize the memory you get unpredictable results.
dmckee
If you are also going to use `realloc()`, you must deal with the fact that the extra memory is not zeroed - so you probably need your initialization code to do the job thoroughly (enough). Obviously, if you `calloc()` the memory and will never `realloc()` it, then this doesn't matter.
Jonathan Leffler
"will, consist of seemingly random data" - for certain values of "random". Statistical tests will most likely be able to distinguish it from successive samples of a uniformly-distributed discrete random variable over the range 0 ... UCHAR_MAX ;-)
Steve Jessop
+4  A: 

To be accurate:

which is useful in avoiding unpredictable behavior and crashes in certain cases

should read:

which is useful in HIDING unpredictable behavior and crashes in certain cases

anon
+2  A: 

"To clear the memory" in this case means to fill it with physical all-zero bit pattern. Note, that from the formal point of view, this kind of raw memory initialization is only guaranteed to work with integral types. I.e. objects of integral types are guaranteed to receive initial values of zero. Whether any other types will be meaningfully initialized by this is implementation-defined. (It takes additional standards that go beyond the limits of C standard to give the extra guarantees. POSIX, IEEE 754 etc.)

Whether using calloc to "prevent crashes" as described in the quote actually makes sense is a different question. I'd say that it can indeed improve stability of the code written by lazy programmers in a sense that it will fold all possible unexpected behaviors triggered by various garbage values into one specific unexpected behavior triggered by all-zero values.

AndreyT