-1

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.

Mohammad Karmi
  • 1,403
  • 3
  • 26
  • 42
  • C does not support exceptions. And the compiler is not involved in running a program it compiled. You might want to read about the differences between compiler and interpreter. – too honest for this site Oct 22 '16 at 19:59
  • Then what is segmentation fault ? , I know the deference between them what I meant is the program should exit because it was out of size. – Mohammad Karmi Oct 22 '16 at 20:02
  • So you tell the compiler should crash during compilation, or what? Anyway, segfault is nothing the C standard defines. Your code invokes undefined behaviour. Be happy not to get nasal daemons. – too honest for this site Oct 22 '16 at 20:02
  • I said " the program should exit" which means run time not during compilation, not sure what is your problem I already got the answer below and it is answering my question – Mohammad Karmi Oct 22 '16 at 20:04
  • If you read and understand the answer, you should know - by now - there is no guarantee about any specific behaviour - that's why it is called "**undefined**". In general it is good not to assume something. Apparently you do know your code is wrong. C does not prevent you from shooting your foot. See all the hobbling C beginners. – too honest for this site Oct 22 '16 at 20:07
  • I didn't write a code to use that, what I said "I wonder" which means is that expected , and why it happens. thanks for your comments though – Mohammad Karmi Oct 22 '16 at 20:10

3 Answers3

3

Accessing data out of bounds gives you undefined behavior, which means anything can happen.

If you go far out of bounds, segmentation faults are to be expected due to accesses to unmapped or protected memory pages. However that assumes a somewhat straightforward mapping of your code to machine code.

The truth is, the compiler only gives you the illusion that your code maps straightforwardly to machine code. The moment you break the rules by causing undefined behavior, the illusion may break in some very bizarre ways and that's what undefined behavior is all about.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
2

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.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

Sorry, you cannot know the size of an allocated array (see: determine size of dynamically allocated memory in c)

whether accessing an out of bounds array will throw "exception" or not depends on the location of the array / the MMU boundaries. Anyhow, it's not to be relied upon!

To get "real" exceptions, switch to C++, drop the calloc, use vector::at.

Community
  • 1
  • 1
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219