-1

I have a doubt regarding memory allocation to the arrays in C. Like in this snippet I assigned the array size 4 but in the next line, I accessed a location that is not part of the array but still there is no error in execution.I don't understand how it is working.

int main()
{  int arr[4];
   arr[5] = 35;
   printf("%d\n",arr[5]);
   return 0;
}
Costantino Grana
  • 3,132
  • 1
  • 15
  • 35
MridulRao
  • 68
  • 1
  • 6
  • 4
    The behavior of undefined behavior is undefined. Do not expect anything. Also, C++ is not C. Do not tag C questions as C++, please. – paddy Oct 07 '20 at 04:23
  • An array is allocated at runtime by allocating some space in the memory. In the above case, it might be possible that the adjacent memory location was free and as a result you were able to store a value in it. It might not be the case everytime. – GhostVaibhav Oct 07 '20 at 04:25
  • 1
    C doesn't have any kind of bounds-checking. Going out of bounds leads to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior), and it's your responsibility as the programmer to make sure that never happens. – Some programmer dude Oct 07 '20 at 04:32
  • @Someprogrammerdude: C does have bounds checking. Annex K is literally called “Bounds-checking interfaces.” – Eric Postpischil Oct 07 '20 at 05:08

3 Answers3

2

C will not prevent you from accessing memory you should not access. There is no safety barrier, no blinking lights or warning sirens. It's just a sheer drop off a cliff with not even so much as a railing in the way.

Remember when writing C code: It's your job as the programmer to ensure you're not going out of bounds.

Anything out of bounds is termed undefined behaviour which is akin to driving your car off the road. You might just end up on some grass, or you might careen off a mountain. It's dangerous and unless you know exactly what you're doing you shouldn't do it.

There are cases where you know something the compiler doesn't and C won't get in the way. When writing embedded software on extremely limited systems this may be the case, but normally it isn't.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • And the reasoning: C++ has a policy of not making a program pay for behaviour it doesn't ask for. Checking for running off the end of the buffer requires checking. While an attentive enough compiler could catch this one and raise a warning (not a required behaviour, so don't expect it) in the general case the test needs to be performed at runtime, and that has a performance cost on each and every array access. A correct program will never write out of bounds, so checking the bounds would be a performance penalty for a correct program. – user4581301 Oct 07 '20 at 04:36
  • 1
    @user4581301 Roughly the same holds for C, which is what I believe this question is about. C++ does do *some* checking in some cases. – tadman Oct 07 '20 at 04:39
  • 1
    Good point. I got pulled here by the C++ tag. – user4581301 Oct 07 '20 at 04:40
2

Accessing an array out of bounds in C and C++ is "undefined behavior", meaning the compiled executable does not guard against these errors, and "anything could happen". This means the program could crash, or worse, keep going and subtly corrupt memory. In your example, try this:

int main()
{
    int arr[4];
    int x = 0;

    arr[4] = 35;
    printf("%d\n", x);
    return 0;
}

If things are placed on the stack one after the other, the printf should print 35 for x, even though we modified arr[4]. It just happened that x was in the adjacent memory location. It could also very well print something else - it's undefined behavior.

Alexander Kondratskiy
  • 4,156
  • 2
  • 30
  • 51
0

The arr[5] you're accessing is outside of the allocated space for your arr array in the stack memory. For every C program, there is a block of memory created for the stack memory (see here for details regarding the memory layout of the C program) you can access and write the data in that address arr[5] but it will cause undefined behavior such as overriding a stack register (see here for more info on the stack register/pointer) depending on different architecture

VietHTran
  • 2,233
  • 2
  • 9
  • 16
  • 1
    Careful there. Note the "A typical memory representation of C program" at the beginning of the first link. Little of what is discussed is required by the C standard. These are implementation details. It's pretty rare to see an implementation not based on stack and heap, but what of multi-threaded programs with multiple stacks? Kind of makes a mess of the whole stack at top concept. – user4581301 Oct 07 '20 at 04:44