+ 1
What will happen when an array b has 5 valuse and cout b[6], what will be the output.
I have confusion in when I insert cout<<b[6] then also it display a value while I have given only 5 values. see the code I attached. https://code.sololearn.com/cJxia30gDT83/?ref=app
10 Réponses
+ 2
Undefined behavior is what happens.
+ 2
@Vincent Blankfield It is not defined. C++ does not define if the memory you are accessing is valid or not, nor what will happen if you try to access it. It's completely dependent on the OS or hardware when there is no OS, not C++. That is what undefined behavior means.
+ 1
c++ doesn't control the bounds of an array. An array is located in the computers memory. So b[6] just outputs a garbage that is located at b+6*sizeof(int) memory location. If that memory location is allowed to be read, you get an output. If that address happened to be protected from reading, you would get a runtime error (mb you've seen such error on Windows, saying that memory couldn't be read).
+ 1
actually I don't get one thing why did it show a numeric value, it can also show error
+ 1
Computer memory itself is a huge array. Address in it is an index in that array. Your array is located somewhere in that memory. For example at address 42. Let's assume that an integer has size 4. So first element would be located starting at address 42, second - 42+4, third - 42+(2*4), and so on. So, when going out of bounds, you're just reading a memory value outside your array. In case of b[6] it's address of &b[0]+6*siseof(int). If b is located at address 42 and sizeof (int) = 4, then b[6] is reading memory address 42+6*4 = 66 and outputs any garbage value that was there.
+ 1
To all the silent minusers.
First of all, the question was: "What will happen when an array b has 5 valuse and cout b[6], what will be the output." I explained exactly what will happen.
Second. Regarding if going out of bounds is an undefined behaviour. Let me quote the standard: (quote ommited because of comment length limit. See "ISO/IEC JTC1 SC22 WG21 N3690" 1.3.24 and 5.2.1)
So, according to 1.3.24, undefined behavior is: "behavior for which this International Standard imposes no requirements", but according to 5.2.1: "The expression E1[E2] is identical (by definition) to *((E1)+(E2))". So it's pretty defined, that no materr what x is, arr[x] would translate to *(arr+x). According to the note in 1.3.24, the compiler develorers are free to define any behaviour they like in cases of UB (kind of), but in this case, the standard explicitly states what to do with T[S] expressions, no matter what S is.
As for what will be in the memory at runtime — this isn't a C++'s business. The same as C++ is not responsible for the contents of files a C++ program reads or user input it receives.
And an example of going out of bounds, that is completely defined:
int arr[10][10];
for (int i=0; i<10; i++)
for(int j=0; j<10; j++)
arr[i][j] = i*10+j;
for (int i=0; i<100; i++)
cout << "arr[0][" << i << "] = " << arr[0][i] << endl; // Am I going out of bounds with arr[0][99]?
cout << "\n*(*(arr+4)+2) = " << *(*(arr+4)+2) << ", so is arr[4][2] = " << arr[4][2] << endl;
Everyone is very welcome to prove I'm wrong, quoting the standard, I really curious why it's so popular to call this an UB when the standard pretty well defines what an implementation should do.
+ 1
And the quote from the standard that didn't fit into my previous comment:
ISO/IEC JTC1 SC22 WG21 N3690
1.3.24
undefined behavior
behavior for which this International Standard imposes no requirements
[Note:
Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.
— end note]
5.2.1 Subscripting
1
A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is of type “T”. The type “T” shall be a completely-defined object type. The expression E1[E2] is identical (by definition) to *((E1)+(E2))
[Note: see 5.3 and 5.7 for details of * and + and 8.3.4 for details of arrays. — end note], except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise
2
A braced-init-list shall not be used with the built-in subscript operator.
- 1
@aklex
Behavior is well defined. But the result may be unexpected if one did this by mistake. If the array is placed on the stack, it's even possible to predict what would be outputted. Actually, stack overflow attacks use this.
- 1
It's hard to explain better without drawing a picture...
In short: just don't go out of array bounds, and have in mind that C++ won't tell you if you do.
- 1
C++ defines the behavior of [] operator of array, and it doesn't define what would be at the memory location. So behavior is defined - with arr[n] you will access sizeof(arr) * n + &arr[0] address in memory. But result (what would be at that location) is not defined, neither it should be.
Also, it doesn't always depend on the runtime environment what would be read by this array misuse: if the aray is on the stack, you will read a local variable next to it. But this is more of an exception than a rule, and a lot of factors need to be taken into account to be sure with the outcome.