Search code examples
ccalloc

using non allocated space calloc


I just wonder that the compiler doesn't throw exception when I use non allocated space , here is a code for example:

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

int main()
{
   int i, n;
   int *a;

   printf("Number of elements to be entered:");
   scanf("%d",&n);

   a = (int*)calloc(n, sizeof(int));
   printf("Enter %d numbers:\n",n);
   for( i=0 ; i < n ; i++ ) 
   {
      scanf("%d",&a[i]);
   }

   printf("The numbers entered are: ");
   for( i=0 ; i < n ; i++ ) 
   {
      printf("%d ",a[i]);
   }
   free( a );

   return(0);
}

if n=3 for example and I statically said:

a[10]=3;

it will work and doesn't throw exception and I can print it, so what is the impact of using an element out of bound ? and is there a way to know the size ? because (sizeof) wont work on the calloc array.


Solution

  • You have some dreaded undefined behavior (UB). Read Lattner's blog about What every C programmer should know about undefined behavior.

    Notice that with UB, very bad things could happen, or nothing serious. And the observed behavior might not even be reproducible from one run to the next one (read about ASLR).

    To explain what is happening on your system, you need to dive into implementation details, much lower than the C or C++ code. You could for example ask for the generated assembler (e.g. compile your code with gcc -Wall -O -fverbose-asm -S and look into the generated *.s assembler file). Or you could use (on Linux) something like strace(1) to understand the involved system calls. I'm imagining that on Linux, the call to calloc would ask the kernel for at least one page of heap data (i.e. calloc would use mmap(2) or sbrk(2) ....) and since a page is 4Kbytes of data, the bytes you are accessing are in fact in your virtual address space.

    BTW, I invite you to install and use some Linux distribution. Since it is mostly made of free software, you could study the involved source code (both your code, the standard C library, and the Linux kernel, perhaps even the compiler). That could take you many years, but you'll be able in principle to understand all the implementation details.

    Read also Joel's law of leaky abstractions...

    is there a way to know the size ? (of some heap-allocated data)

    No, not in portable C. You should manage the size itself (i.e. have some way to know it). A useful trick might be to keep it near the array data, e.g. in a struct containing the size, and ending with a flexible array member. But you still need some convention to get the size.