Hi,
What is the advantage of zeroing out memory (i.e. calloc over malloc)? Won't you change the value to something else anyways?
-Chris
Hi,
What is the advantage of zeroing out memory (i.e. calloc over malloc)? Won't you change the value to something else anyways?
-Chris
Assume you want to write a counting sort implementation, or depth first search a graph and keep track of visited vertices. You'll update your memory as the algorithm runs (rather than assigning a value just once). You need to initialize it to zero at the beginning. If you didn't have calloc
, you'd have to manually go through it and initialize it to zero at the beginning of your algorithm. calloc
can potentially do this more efficiently for you.
calloc
ing a structure with pointers: they are initialized to NULL.In a realtime process control system I worked on long ago, we settled on having the power-on logic initialize all of RAM to 0xCC, the 8086's interrupt 3
instruction. This would cause the processor to enter the monitor (a primitive debugger) if it somehow executed uninitialized memory. (Unhelpfully, the 8086 merrily executes memory containing zeros since they are add [bx+si],al
instructions. Even 32-bit mode causes them to be add [ax],al
instructions.)
I don't recall if we ever found a runaway program, but the values corresponding to 0xCC in various values: 52,428 (unsigned 16 bit), -19,660 (signed 16 bits), -107374176 (32-bit float), and -9.25596313493e+61 (64-bit float) popped up in a lot of unexpected places. Also, some code expecting characters to be 7 bit ASCII—that is, a bug—alerted us to its presence when it tried to process 0xCC.
In addition to the benefits of initializing variables calloc also helps track down bugs.
If you accidently use a bit of the allocated memory without properly initializing it the application will always fail the same way. For example with a access violation from a null pointer. With malloc the memory has random values and this can cause the program to fail in random ways.
Random failures are very hard to track down and calloc helps avoid those.
There are two camps: one says that initializing variables when they are declared helps find bugs. The people in this camp make sure everything they declare is initialized. They initialize pointers to NULL
, int
s to 0, etc. The idea is that everything is determinate, and when they see a NULL
-pointer in a debugger, they immediately know it wasn't set properly. It can also help your program crash during testing because of NULL
-pointer dereferencing rather than mysteriously crashing in production runs.
The other camp says that initializing variables at declaration makes things harder to debug, because now a compiler can't warn you about variables "used without being set".
Without telling you my personal preference1: if you belong to the first camp, you would want to calloc()
instead of malloc()
. If you belong to the second camp (which apparently you do) then you prefer malloc()
over calloc()
.
Now there are two exceptions:
calloc()
but malloc()
because you are initializing floating-point numbers or pointers, and you know that all bits zero doesn't necessarily mean 0
for them. Or, you don't want the extra overhead.calloc()
when you are allocating some data and want it to be all zeroes. For example, if you want to calculate the row-wise sum of an n
by m
dynamically allocated int
data.1 You can see my answers to many of the questions here on SO to see which camp I belong to :-).
First of all you cannot calloc pointers, at least not if you want to follow standard C.
Second, bugs just becoming masked when you clobber the member with all zeros. It is much better practice to have a debug version of malloc that initialises the memory to something that will always crash, such as 0xCDCDCDCD.
Then when you see an Access voilation you know the problem straight away. It is also beneficial to have debug free function that will whip thje memory with a different pattern so those who touch the memory after it is freed get an unexpected surprise.
Working on an embedded system, callocing just to "be sure" is usually not an option. You typically allocate and populate in one go so calloc just mens you are double touching memory.