C / C++ FAQs & Programming Resources - ProkutFAQ : MallocCallocDifference

HomePage Recent Changes Recently Commented Login/Register

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.

Advanced section

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:

int* ptr=calloc(10,sizeof(int));

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:

int** ptr=calloc(10,sizeof(int*));

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.
 Comments [Hide comments/form]
Actually, prefer calloc to malloc: malloc has size restrictions on allocation size which are not realistic anymore.
The null/zero problem in advanced section is not really accurate : it is understood that calloc is similar to malloc + memset() : it can at best be a newbie note and a caveat while using it for pointers, not a reason for preference to calloc as compared to malloc.

- Mridul
-- byethost15.com (2006-11-28 22:59:03)
Mridul,

Care to expound why the null/zero section in the advanced section is not accurate? Yeah I agree that calloc is malloc+memset but there are a few intricacies as I mentioned and please check comp.lang.c for further differences (which I didnt include here because I tend to digress a bit too much).
-- PriyaSridharan (2006-12-11 20:25:55)
It is similar to "int **ptr = (int **)malloc(sizeof(int*) * size); memset(ptr , 0 , sizeof(int*) * size);"

So, the note is not really adding much - except as a caution that it need not work as desired since memset does not work as desired when setting pointers to 0. It would be a note about memset, and my association - on calloc : not really only of calloc.

Btw, you did not mention anything about the size restrictions of malloc.
-- dsl-KK-dynamic-152.107.22.125.airtelbroadband.in (2006-12-13 16:30:18)
Yeah but people need to be informed about the potential pitfalls and that is the reason why I have included that here.

And what size restrictions are you talking about? As far as I know the restrictions that apply to malloc also apply for calloc.

One problem that people often talk about is that is say if you want to allocate space for 2^30 long double values. In that case if you call malloc like malloc((2<<30)*sizeof(long double)) then the multiplication will overflow.

In the case of calloc this may not be a problem because calloc call would look like this

calloc(2<<30,sizeof(long double)), but since even here a multiplication happens behind the scene this would in all probability overflow too. So what memory restrictions are you talking about? Am not aware of any
-- PriyaSridharan (2006-12-16 21:09:13)
In the latter case, there will not be an overflow in a decent library (which handles 64 bits that is).
And not just double - consider allocating for a struct which is of nontrivial size.
-- dsl-KK-dynamic-242.82.22.125.airtelbroadband.in (2007-01-02 10:59:54)
@above

I checked GNU's implementation and Open Watcom's implementation and it looks like they will surely overflow. When we get down to discussing the implementation of libraries, we enter the realm of implementation defined behavior and I would like to keep the scope of this article well within the realms of what has been mentioned in the standard. And in the standard they havent mentioned any specific issues where calloc should be preferred over malloc.
-- PriyaSridharan (2007-01-05 02:57:20)
Bugs in library is a different thing - the api does not allow overflow upto 64 bits.
if an impl does not use it (like some other do allow it), that is a different matter.

btw, check the impl of libc for 64 bits.
-- dsl-KK-dynamic-142.84.22.125.airtelbroadband.in (2007-01-07 12:52:32)
btw, just to mention - definition is as size_t : which just gets mapped to an int ... need not be so, but usually is.
-- dsl-KK-230.48.246.61.airtelbroadband.in (2007-01-08 20:47:57)
Page was generated in -0.7312 seconds