Search code examples
ccalloc

How much memory does calloc actually allocate?


The following code when tested, gives output as

1
0
0
2
0

which is amazing because ptr[3], ptr[4] did not have any memory allocation. Although they stored value in them and prints it. I tried the same code for few larger i's in ptr[i] which again compiled successfully and gives result but for very large value of i, of the order of 100000,program get crashed. if calloc() allocates such a large memory on single call then it is not worth effective. So how calloc() works? Where is this discrepancy?

#include <stdio.h>
void main() {
    int * ptr = (int *)calloc(3,sizeof(int));//allocates memory to 3 integer
    int i = 0;
    *ptr = 1;
    *(ptr+3) = 2;//although memory is not allocated but get initialized
    for( i =0 ; i<5 ; ++i){
        printf("%d\n",*ptr++);
    }
}

After that i tried this code which continuously runs without any output

#include <stdio.h>
void main() {
int * ptr = (int *)calloc(3,sizeof(int));
int i = 0;
*ptr = 1;
*(ptr+3) = 2;
//free(ptr+2);
for( ; ptr!=NULL ;)
{
    //printf("%d\n",*ptr++);
    i++;
}
printf("%d",i);
}

Solution

  • You are confounding two kinds of memory allocation: the kernel's and libc's.

    When you ask malloc or calloc for 5 bytes, it does not turn around and ask the kernel for 5 bytes. That would take forever. Instead, the libc heap system obtains larger blocks of memory from the kernel, and subdivides it.

    Therefore, when you ask for a small amount of memory, there is usually plenty of more accessible memory right after it that has not been allocated yet by libc, and you can access it. Of course, accessing it is an instant recipe for bugs.

    The only time that referencing off the end will get a SIGnal is if you happen to be at the very end of the region acquired from the kernel.

    I recommend that you try running your test case under valgrind for additional insight.