向量的大小= 2,但它仍然在索引100

时间:2017-04-03 02:53:47

标签: c++ c++11

我在http://cpp.sh/中运行以下代码。 输出显示name1.size()= 2,但name1 [100] = 10;

// Example program
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    vector<vector<int>> name;
    vector <int> name1;
    name1.push_back(1);
    name1.push_back(3);
    vector <int> name2;
    name2.push_back(4);
    name.push_back(name1);
    name.push_back(name2);
    name1[100]=10;
    cout<<name1.size()<<endl;
    cout<<name1[100];
}

2 个答案:

答案 0 :(得分:2)

简短的回答是您正在调用未定义的行为,因此您将无法进一步了解标准中必须发生的事情。

答案很长,C ++是一种不安全的语言,并不保证各种无效操作的任何类型的确定性错误,包括使用vector访问operator[]越界。相反,它使用广泛的未定义行为,基本上允许任何发生:通过允许用户灵活地避免他们知道的检查,这个想法是对于性能良好的代码,可以实现冗余,良好的性能。

如果你想让向量检查你是否没有访问越界索引,没问题 - 只需使用完全相同的vector::at(),并抛出std::out_of_range进行无效访问

至于为什么你的特定代码(显然)返回一个值,请注意operator[]的典型 1 实现只是直接访问底层存储,这意味着在汇编级别您将从向量底层的存储开始访问任何100 * sizeof(int)个字节。这通常是堆上随机的东西(因为存储通常在堆上分配),但它也可能是一个无法访问的地址,导致访问冲突。

1 某些编译器(如MSVC)将在“调试”模式下提供更多错误检查,这可能会导致operator[]调用vector.at(),而会执行<{1}} / em>进行范围检查并定义了行为,并且至少有一些其他编译器/标准库似乎正在加入这个想法。

答案 1 :(得分:0)

试试此代码here

您宣布:

vector <int> name1; // An empty vector. name1.size = 0 here.

推送后两个值。

name1.push_back(1);
name1.push_back(3); // name1.size = 2, Index starts at 0, so
                    // name[0] = 1 and name[1] = 2

所以值为:

name1[100] = undefined (garbage). // You never initialised this value, so it yields unexpected behaviour.

另一种方法是使用int向量的默认初始化器并将其声明为:

vector <int> name1(101);

这里:

name1[100] = 0 // Because you defined it in the vector constructor to initialise 100 default values.
name1[0] = 0 // This is the first value of the now initialised vector.
name1[69] = 0 // This is the 70th value of the initialised vector.
name[101] = undefined // Again, this is undefined (garbage). You defined a vector of size n = 101, so that means the vector's range is [0,100]. 0 index counts and the last value is n - 1 (101 - 1 = 100). Index 101 is undefined.