Accessing an array out of bounds gives no error, w

2018-12-30 23:29发布

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.

标签: c++ arrays
17条回答
孤独寂梦人
2楼-- · 2018-12-31 00:13

When you write 'array[index]' in C it translates it to machine instructions.

The translation is goes something like:

  1. 'get the address of array'
  2. 'get the size of the type of objects array is made up of'
  3. 'multiply the size of the type by index'
  4. 'add the result to the address of array'
  5. 'read what's at the resulting address'

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.

查看更多
旧人旧事旧时光
3楼-- · 2018-12-31 00:16

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 for std::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.

查看更多
像晚风撩人
4楼-- · 2018-12-31 00:17

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

查看更多
孤独寂梦人
5楼-- · 2018-12-31 00:17

When you initialize the array with int array[2], space for 2 integers is allocated; but the identifier array simply points to the beginning of that space. When you then access array[3] and array[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 like array[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

查看更多
千与千寻千般痛.
6楼-- · 2018-12-31 00:17

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];

查看更多
梦醉为红颜
7楼-- · 2018-12-31 00:19

Using g++, you can add the command line option: -fstack-protector-all.

On your example it resulted in the following:

> g++ -o t -fstack-protector-all t.cc
> ./t
3
4
/bin/bash: line 1: 15450 Segmentation fault      ./t

It doesn't really help you find or solve the problem, but at least the segfault will let you know that something is wrong.

查看更多
登录 后发表回答