I am assigning values in a C++ program out of the bounds like this:
#include <iostream>
using namespace std;
int main()
{
int array[2];
array[0] = 1;
array[1] = 2;
array[3] = 3;
array[4] = 4;
cout << array[3] << endl;
cout << array[4] << endl;
return 0;
}
The program prints 3
and 4
. It should be not be possible. I am using g++ 4.3.3
Here is compile and run command
$ g++ -W -Wall errorRange.cpp -o errorRange
$ ./errorRange
3
4
Only when assigning array[3000]=3000
does it give me a segmentation fault.
If gcc doesnt check for array bounds, how can I be sure if my program is correct, as it can lead to some serious issues later?
I replaced above code with
vector<int> vint(2);
vint[0] = 0;
vint[1] = 1;
vint[2] = 2;
vint[5] = 5;
cout << vint[2] << endl;
cout << vint[5] << endl;
and this one is also produces no error.
When you write 'array[index]' in C it translates it to machine instructions.
The translation is goes something like:
The result addresses something which may, or may not, be part of the array. In exchange for the blazing speed of machine instructions you lose the safety net of the computer checking things for you. If you're meticulous and careful it's not a problem. If you're sloppy or make a mistake you get burnt. Sometimes it might generate an invalid instruction that causes an exception, sometimes not.
libstdc++, which is part of gcc, has a special debug mode for error checking. It is enabled by compiler flag
-D_GLIBCXX_DEBUG
. Among other things it does bounds checking forstd::vector
at the cost of performance. Here is online demo with recent version of gcc.So actually you can do bounds checking with libstdc++ debug mode but you should do it only when testing because it costs notable performance compared to normal libstdc++ mode.
g++ does not check for array bounds, and you may be overwriting something with 3,4 but nothing really important, if you try with higher numbers you'll get a crash.
You are just overwriting parts of the stack that are not used, you could continue till you reach the end of the allocated space for the stack and it'd crash eventually
EDIT: You have no way of dealing with that, maybe a static code analyzer could reveal those failures, but that's too simple, you may have similar(but more complex) failures undetected even for static analyzers
When you initialize the array with
int array[2]
, space for 2 integers is allocated; but the identifierarray
simply points to the beginning of that space. When you then accessarray[3]
andarray[4]
, the compiler then simply increments that address to point to where those values would be, if the array was long enough; try accessing something likearray[42]
without initializing it first, you'll end up getting whatever value happened to already be in memory at that location.Edit:
More info on pointers/arrays: http://home.netcom.com/~tjensen/ptr/pointers.htm
when you declare int array[2]; you reserve 2 memory spaces of 4 bytes each(32bit program). if you type array[4] in your code it still corresponds to a valid call but only at run time will it throw an unhandled exception. C++ uses manual memory management. This is actually a security flaw that was used for hacking programs
this can help understanding:
int * somepointer;
somepointer[0]=somepointer[5];
Using g++, you can add the command line option:
-fstack-protector-all
.On your example it resulted in the following:
It doesn't really help you find or solve the problem, but at least the segfault will let you know that something is wrong.