What are the differences between allocation of memory using malloc() and calloc() ?
Unlike malloc, calloc zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. There are however some problems associated with calloc. For more information check out the Advanced Section
at the end of this article.
If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesn't matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to undefined behavior.
There is one reason why people might prefer using calloc over malloc. Normally when people want to allocate memory large enough to hold num
elements where each element is size
bytes large, they would call malloc like this:
<type of the element>* ptr=malloc(num*size);
But there is a problem here. What if num were very large so that the multiplication num*size causes an overflow on a size_t variable? On some systems when such an overflow occurs, the value is rounded down and the resulting value would be very different and much smaller when compared to the original result. And so malloc would attempt to allocate memory of that size and if successful it would return a pointer to this block of memory whose size would be very different from what we requested in the first place. This is bound to cause problems at a later point of time. A call to calloc like this <type of the element>* ptr=calloc(num,size);
seems like a much better option. But you can rest assured that if the memory requested is so large so as to cause an overflow on a size_t value then the requested block of memory would be too big to fit into the memory available on most computers. So the usage of calloc doesn't improve the situation much and such a call is bound to fail anyway.
It is often better to avoid the usage of calloc as far as possible. Use it only when you have to. For everything else there is malloc.
As has already been mentioned before, calloc zeroes out the memory that it allocates which means that every bit in the memory block allocated by calloc is zero. People might find this useful at times. For eg: if they wanted to allocate a block of memory large enough to hold 10 integer values an if they wanted to initialize all these values to zero then all that they have to do is to call calloc like this:
Here all the int values are zero to start out with. Hmmm that was very easy.
Now suppose someone else wanted to allocate memory for 10 int* variables and wanted to initialize all these values to NULL i.e he/she wanted all the int* pointers to be zero. Now you might think that we could use calloc again for this like this:
But you are horribly wrong here. The 10 int*
pointers that you have here may or may not be null pointers. The zero-fill is guaranteed to yield zero value for all int types (including char) but it does not guarantee null values for pointers and zero values for floating points.
A null pointer is something that is distinguishable from all other pointers and is guaranteed to compare unequal to any pointer that points to any object or function. And how can null pointers be generated? It is again guaranteed by the standard that assigning zero to a pointer makes that pointer a null pointer. Read it carefully again. "Assigning zero to a pointer makes that pointer a null pointer"
. This does not mean that the memory region in which the null pointer is stored is filled with zeroes.
When you assign zero to a pointer, things happen under the hood which guarantees the return of a null pointer. What happens underneath is implementation defined and in particular architecture dependent. So different compilers might follow different methods.
So when you use calloc to allocate memory to store 10 int* null pointers, you would go horribly wrong. What you have here are not 10 null pointers. They could be anything (it is fairly obvious that they wont be pointing to a well defined region of memory). So it is better not to use calloc to allocate memory for pointers and if you do, you better not assume that these are null pointers.
For more info on NULL and null pointers please refer to C-FAQ∞