Array Out Of Bounds Allowed?

Started by
9 comments, last by Matt-D 12 years, 5 months ago
Hey everyone,

How come I can access non-existent array values and not get any errors??? It just prints 0 when the index is out of bounds, as if the value of that index is 0. Please explain.

#include <iostream>

using namespace std;

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int main()
{
for (int i = 0; i < 10; i++)
{
cout << arr << endl << endl; // this works as expected
}

cout << arr[10] << endl // this prints 0
<< arr[11] << endl // this prints 0
<< arr[22]; // this prints 0 as well. No errors, nothing.

return 0;
}


Using Code::Blocks.
I'd definetly say that a glass is half-empty!
Advertisement
Welcome to the wonders of C and C++. Arrays little more than pointers in memory, with the index you specify being N*sizeof(arrayType) from that pointer. If you specify more than the array, you can read/write to some bit of memory outside of the array. This used to be the source of like 95% of computer exploits (though cross site scripting, SQL injection, and the fact that few people use C or C++ anymore have reduced that figure significantly).

That you happened to get 0 while going out of bounds is chance.
A valid C++ implementation is not obliged to perform bounds checking on array access. Many will put limited bounds checking in debug mode. For example, were the array dynamically allocated, and you wrote past the end, when you deallocate the array the heap code can sometimes detect this and report an error.

Technically speaking your program is ill-defined as it uses what the C++ standard calls "undefined behaviour". There is no requirement for the compiler or runtime to try and detect or handle such usage. Indeed, undefined behaviour is often used when such detection would be expensive to perform. This allows C++ compilers to generate efficient code, they don't need to account for the programmer misbehaving. This design mentality is summed up as the programmer is always right.

This is one of the reasons why containers like std::vector are preferred, in debug mode they can do full bounds checking.
Thank you for your replies! I was aware that it's bad practice and shouldn't be done. But I thought this kind of code results in an error, program crash, memory leak etc.
My question was: why is the result simply 0? Nothing wrong, just 0? How come these random memory addresses are 0? Why not 0xfff00 or something?
I'd definetly say that a glass is half-empty!
Ok, this is what Visual C++ 2010 does:
"'console.exe': Loaded 'C:\Documents and Settings\Gleb\My Documents\Visual Studio 2010\Projects\console\Release\console.exe', Symbols loaded.
'console.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', Cannot find or open the PDB file
'console.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', Cannot find or open the PDB file
'console.exe': Loaded 'C:\Program Files\AVAST Software\Avast\snxhk.dll', Cannot find or open the PDB file
'console.exe': Loaded 'C:\WINDOWS\system32\msvcp100.dll', Symbols loaded.
'console.exe': Loaded 'C:\WINDOWS\system32\msvcr100.dll', Symbols loaded.
The thread 'Win32 Thread' (0x8a8) has exited with code -1073741510 (0xc000013a).
The program '[3036] console.exe: Native' has exited with code -1073741510 (0xc000013a)."

and the out of bounds values are: 1, 374455, 0

Code::Blocks still just prints three zeroes.

That's my question. I know VC++ and CB are different, but what's the underlying reason for such behavior? I'm accessing random memory, why does CB return zeroes and VC returns something else? Exact same source.
I'd definetly say that a glass is half-empty!

Thank you for your replies! I was aware that it's bad practice and shouldn't be done. But I thought this kind of code results in an error, program crash, memory leak etc.
My question was: why is the result simply 0? Nothing wrong, just 0? How come these random memory addresses are 0? Why not 0xfff00 or something?


The results of undefined behavior are... undefined. There is no definition for what should happen, so what's the point of asking why an undefined result is a certain way?It doesn't really matter.

The real explanation lies in the implementation details, which is something you should probably avoid.
Xcode would tell u that the array is out of bound as a compiler warning!

I open sourced my C++/iOS OpenGL 2D RPG engine :-)



See my blog: (Tutorials and GameDev)


[size=2]http://howtomakeitin....wordpress.com/


My question was: why is the result simply 0? Nothing wrong, just 0? How come these random memory addresses are 0? Why not 0xfff00 or something?


It's not a random memory address, it's the int value of the bits at that memory address. Sometimes it will not be 0. Sometimes that memory address will be invalid and you'll crash. Sometimes that memory address will be different variables in your program. Sometimes that memory address will be the actual instructions that your program is.

It is an error as far as you made a mistake, but C and C++ make no guarantees about what happens when you do it. They do that a lot.

That's my question. I know VC++ and CB are different, but what's the underlying reason for such behavior? I'm accessing random memory, why does CB return zeroes and VC returns something else? Exact same source.


Undefined behavior, as has been said. It may only return zeros only on Thursdays, or if your last name is "Smith", or if you are wearing a red shirt. Although this is obviously just a humorous answer, it's just about as useful an answer* you may get. The fun** part is that such undefined behavior can also cause crashes, in seemingly unrelated and completely different parts (of seemingly valid!) code -

but only on Thursdays, or if your last is "Smith", or if you are wearing a red shirt. :)

* Some compilers (and probably only on debug builds) will fill in certain memory areas with specific values in order to more easily track down memory bugs.

** Not really fun, these types of bugs are notoriously frustrating to squash.

Xcode would tell u that the array is out of bound as a compiler warning!


So would g++ if you compiled with -Wall (all warnings enabled), as you should. I would be surprised if Visual C++ doesn't warn about something as blatant as this.

Someone said that "undefined behavior" means "it works when you first try it, it passes all your tests and it explodes in your face when you are showing the program to your boss or your most important customer." :)

This topic is closed to new replies.

Advertisement