1

I want to know in c language, if I have an array whose length is 3, if i try to access the 4th element of the array, which memory address will it point to?

I have read similar problems of accessing array element out of bound, they said that this is a typical undefined behavior which is unsafe, but will there be any common rules for where the 4th element would point to?.

For example, which memory address would the array[3] refer to with declaration given here?

int a = 10; 
int array[3] = {1, 2, 3};
int b = 20;
printf("%d", array[3]); // access the 4th element here

May it point to a or b or array[x] or it's totally random?

The key point here is : if i declared variable A after variable B (especially when they are global variable or static variable), will they be stored continuously in memory? Or it's totally depend on compiler?

Summer Sun
  • 947
  • 13
  • 33
  • Possible duplicate of [Undefined, unspecified and implementation-defined behavior](http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) – n. m. could be an AI Dec 25 '15 at 06:43
  • 6
    When you read *undefined behaviour* somewhere, you **cannot** think abuot "common rules" or anything. It is **undefined** and that's that. – Sami Kuhmonen Dec 25 '15 at 06:43
  • In debug mode, perhaps, it is possible to predict UB. In release compiler would do whatever it wants. For example, it would delete a and b as unused. And array too. – Ivan Ivanov Dec 25 '15 at 07:06

3 Answers3

6

First, to add some clarity to the why part of the undefined behavior that you wrote about, as per C11 spec, you are allowed to write an expression which gives you the address of the element one past the last element, that's fine, but you can not dereference it. The later invokes undefined behavior.

Considering array[3] being the same as *(array + 3), quoting the C11 standard, chapter §6.5.6, Additive operators

[....] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

and

If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

So, to sum this up, (array + 3) will point to the next location of the last element in the array, (i.e., &array[2]) but whether that address will be that of the address of a or b or random memory location, is compiler dependent, entirely.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 1
    Isn't array[x] syntactic sugar for *(array + x)? and in that case, wouldn't it point to the next variable after the array in the stack? – NadavL Dec 25 '15 at 06:43
  • 4
    @NadavL yes, but whether the next address would be that of `a` or `b` is not guaranteed anyway. – Sourav Ghosh Dec 25 '15 at 06:47
  • yes so you mean if i declared variable A after variable B (no matter they are global variable or static), they may not be stored continuously in memory? – Summer Sun Dec 25 '15 at 12:08
4

May it point to a or b or array[x] or it's totally random?

TOTALLY RANDOM :)

artm
  • 17,291
  • 6
  • 38
  • 54
2

This will be totally undefined..

In fact, since those variables are local, they will porbably be sitting on the stack. But depending on your system and/or compiler, some of them (for example a and b in this case) might be stored in a register instead of in memory.

So, your &array[3] will probably be pointing somewhere in the stackspace, pointing to an int further then &array[2], but it is undefined to what value it will point, and accessing it will/should be illegal.

Danny_ds
  • 11,201
  • 1
  • 24
  • 46