我在一个c++程序中分配值,就像这样:

#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;
}

程序输出3和4。这应该是不可能的。我使用g++ 4.3.3

下面是编译和运行命令

$ g++ -W -Wall errorRange.cpp -o errorRange
$ ./errorRange
3
4

只有当分配数组[3000]=3000时,它才会给我一个分割错误。

如果gcc不检查数组边界,我怎么能确定我的程序是正确的,因为它可能导致一些严重的问题以后?

我将上面的代码替换为

vector<int> vint(2);
vint[0] = 0;
vint[1] = 1;
vint[2] = 2;
vint[5] = 5;
cout << vint[2] << endl;
cout << vint[5] << endl;

这个也不会产生误差。


当前回答

The behavior can depend on your system. Typically, you will have a margin for out of bounds, sometimes with value of 0 or garbage values. For the details you can check with memory allocation mechanism used in your OS. On top of that, if you use the programming language like c/c++, it will not check the bounds when you using some containers, like array. So, you will meet "undefined event" because you do not know what the OS did below the surface. But like the programming language Java, it will check the bound. If you step outside of the bound, you will get an exception.

其他回答

C或c++不会检查数组访问的边界。

您正在堆栈上分配数组。通过数组[3]索引数组等价于*(array + 3),其中array是指向&array[0]的指针。这将导致未定义的行为。

在C语言中捕捉这种情况的一种方法是使用静态检查器,例如splint。如果你运行:

splint +bounds array.c

on,

int main(void)
{
    int array[1];

    array[1] = 1;

    return 0;
}

然后你会得到警告:

数组.c:(在函数main中) array.c:5:9:可能超出范围 存储: 数组[1] 无法解决约束的: 要求0 >= 1 需要满足的先决条件: require maxSet(array @ array.c:5:9) >= 1 地址以外的地址 分配的缓冲区。

当然,您正在重写堆栈,但是程序非常简单,因此不会注意到这种影响。

据我所知,局部变量是在堆栈上分配的,所以在你自己的堆栈上越界只能覆盖一些其他的局部变量,除非你oob太多,超过了你的堆栈大小。 由于在函数中没有声明其他变量,因此不会产生任何副作用。尝试在第一个变量/数组之后声明另一个变量/数组,看看会发生什么。

Hint

如果你想要快速约束大小数组的范围错误检查,尝试使用boost::array,(也std::tr1::array from <tr1/array>,它将是下一个c++规范的标准容器)。它比std::vector快得多。它在堆上或类实例内部保留内存,就像int array[]一样。 这是一个简单的示例代码:

#include <iostream>
#include <boost/array.hpp>
int main()
{
    boost::array<int,2> array;
    array.at(0) = 1; // checking index is inside range
    array[1] = 2;    // no error check, as fast as int array[2];
    try
    {
       // index is inside range
       std::cout << "array.at(0) = " << array.at(0) << std::endl;

       // index is outside range, throwing exception
       std::cout << "array.at(2) = " << array.at(2) << std::endl; 

       // never comes here
       std::cout << "array.at(1) = " << array.at(1) << std::endl;  
    }
    catch(const std::out_of_range& r)
    {
        std::cout << "Something goes wrong: " << r.what() << std::endl;
    }
    return 0;
}

这个程序将打印:

array.at(0) = 1
Something goes wrong: array<>: index out of range

使用g++,可以添加命令行选项:-fstack-protect -all。

在你的例子中,结果如下:

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

它并不能真正帮助您找到或解决问题,但至少段错误会让您知道有什么地方出错了。