Can I please have a good detailed explanation on the differences between malloc and calloc? I always have trouble understanding that.

calloc is the same as malloc but calloc initializes the memory to all 0s

Both these are the same

int *array = malloc(10 * sizeof(int));
for(int i = 0; i < 10; i++)
   array[i] = 0;


 The above can be rewritten with this one line:

 int *array = calloc(10, sizeof(int));
Member Avatar for Rahul47

Return type of both is void so don't we have to type cast it ??
Or by directly assigning to 'int' type pointer it is automatically type-casted ?

:-) Good point! This would be more appropriate:

    size_t sz = 10 * sizeof(int);
    int *array = (int*)malloc(sz);
    memset((void*)array, 0, sz);

    /* This does the same thing. */
    int *array = (int*)calloc(10, sizeof(int));

Modern compilers will at least flag the lack of a cast with a warning. Better safe than sorry I think!

Member Avatar for Rahul47

I have a two fold question here.

1) How does malloc differs from calloc in memory allocation. I know that malloc will allocate 1 block of given size and calloc will allocate n block of given size.
So we can use malloc like this:

int *p=(int *)malloc(10*sizeof(int));

which is equivalent to:

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

2) Does calloc initilizes all BLOCKS or all BYTES to 0 ? And, is initializing Blocks/Bytes to 0 is the only reason calloc was introduced?

Return type of both is void so don't we have to type cast it ??

No, C language does not require it, but c++ does.

Modern compilers will at least flag the lack of a cast with a warning.

Might be your compiler. Neither gcc (MinGW) nor Visual Studio 2013 produce that warning.

# include <stdio.h>
# include <stdlib.h>

int main()
{
    int* x = malloc(10 * sizeof(int));
    free(x);
    return 0;
}

I know that malloc will allocate 1 block of given size and calloc will allocate n block of given size.

They allocate exactly the same single block of memory. The only difference is how that block is calculated. With malloc it's calculated by the caller and with calloc it's calculated internally. In fact, you can implement calloc in terms of malloc:

void *calloc(size_t n, size_t size)
{
    size_t blk_size = n * size;
    void *mem = malloc(blk_size);

    if (mem != NULL)
    {
        memset(mem, 0, blk_size);
    }

    return mem;
}

Does calloc initilizes all BLOCKS or all BYTES to 0 ?

There's only one block, and all bytes are initialized to 0. That's why calloc should be used judiciously with non-trivial or non-integral types due to the potential of borking up memory you're not supposed to access or that doesn't represent all bytes zero as a zero value for the type.

I've always said in C you should not cast the return value of malloc (or calloc). That is because if you leave out stdlib.h C will happily let you call the function without a predeclaration (although many C compilers produce warnings for that now but people then have to take note of them) by just assuming it returns int.

If you using most modern 64 bit systems and you do that then

In the presence of a cast
1. C presumes malloc returns int and silently casts your 64 bit pointer to a 32 bit integer.
2. You then let it you know what you are doing with a cast and so it, again silently, casts your 32 bit integer back to a 64 bit pointer.
3. It assigns that value to your pointer and some time later when you try to use it things go very very wrong.

Without the cast
1. C presumes malloc returns int and silently casts your 64 bit pointer to a 32 bit integer.
2. That value is not cast so it tries to assign a 323 bit integer to a 64 bit pointer. This is not allowed without a cast so a compiler error is produced and you find and fix the error. (Hopefully not with a cast*)

Fantastic so that was my normal canned answer, I just checked it on mingw32 and it in fact gave the same 2 warnings in both the cast of casting and not casting which was

warning: implicit declaration of function 'malloc'
warning: incompatible implicit declaration of built-in function 'malloc'

This might still be an issue on less well thought out compilers though.

  • I see too many programmers fixing errors/warnings by adding a cast without thought. The compiler knows what it is doing and if it has emitted an error or warning and you can fix it without a cast you should. A cast switches off all the compilers safty checks.

C presumes malloc returns int and silently casts your 64 bit pointer to a 32 bit integer.

Just because the program is running on a 64-bit operating system doesn't mean malloc() will return a 64-bit pointer. It depends on the compiler, not the operating system. And if the compiler is set to produce 64-bit code it will also produce 64-bit integers.

[edit]Just to prove myself wrong, I tested by compiling a simple program. The size of int is the same for both 32 and 64 bit programs. Oh well, so much for my theory :)

int main()
{
    cout << "sizeof(int) = " << sizeof(int) << '\n';
}

With reference to ur query,
malloc() is a pre-defined function which is available in <alloc.h>. We can also create memory without this function. But, whatever the program without this header file will occupies static memory allocation.For example, if you want to create the memory in dynamic memory allocation then go for malloc(),calloc(),realloc() functions. It is used to create the memory dynamically. It required one argument of type, type_size i.e., datatypesize.
It will create the memory in blocks format.
voidmalloc(type_size);
Ex:-
int
arr;
arr=(int)malloc(sizeof(int)15);//15 is to create number of elements.

calloc() is a pre-defined function which is available in <alloc.h>. It is used to create the memory dynamically. It required two arguments of type, type_size i.e., datatypesize and count (Number of elements to create).It will create the memory in bytes format.
Syntax:-
voidcalloc(count,type_size);
Ex:-
int
arr;
arr=(int)calloc(15sizeof(int));

NOTE:-
It is a permanent memory until u deallocated the memory with the help of free() function.
U can also extend memory by using realloc() function.

malloc() is a pre-defined function which is available in <alloc.h>.

stdlib.h. alloc.h is ancient and non-standardized. Unless you copied that information from a hideously outdated source, I'd recommend updating your knowledge of C. A lot of things have changed since Turbo C, including best practice.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.