0
#include <iostream>
#include <vector>

int main()
{
    std::vector<double> test1(1);

    test1[100] = 5.;

    std::vector< std::vector <double > > test2(1, std::vector<double>(1,0));

    test2[50][100] = 5.;
}

test1: 很好地调整大小和分配内存

test2: "Segmentation fault (core dumped)". 为什么?

注意:不能使用矩阵,因为行大小不相等。

摘要: at(int): 检查边界并在必要时抛出异常 - 无需调整大小

operator[](int):不检查边界 - 不调整大小

push_back()capacity()如果当前容量很小,调整大小会增加一倍

size(): 元素个数vector

capacity(): 在重新分配之前要持有的最大元素是必要的

4

4 回答 4

3

您访问大小为 1 的向量的索引为 100 的元素。您不应访问向量边界之外的索引。事实是,它在第​​一种情况下起作用是纯粹的运气,而不是在第二种情况下不起作用。

向量在调用resize()or时扩展push_back,但简单地访问索引不会扩展向量的大小。相反,它会导致未定义的行为。

要修复代码(更改构造向量时使用的大小):

#include <iostream>
#include <vector>

int main()
{
    std::vector<double> test1(101);

    test1[100] = 5.;

    std::vector< std::vector <double > > test2(51, std::vector<double>(101,0));

    test2[50][100] = 5.;
}
于 2013-01-30T10:25:35.327 回答
1

test1 : 很好地调整大小和分配内存

std::vector 将在调用std::vector::push_back时调整大小并分配内存,但不是通过随机访问运算符随机

test2:“分段错误(核心转储)”。为什么?

下面的代码访问了 test1、test2 的边界:

test1[100] = 5.0;
test2[50][100] = 5.0;

您可以在访问之前测试矢量大小

if (test1.size() > 100))
{
    test1[100] = 5.0;
}  

或者可以将std::vector::at函数与 try/catch 块一起使用:

try
{
    test2.at(50).at(100) = 5.0;
}
catch(const std::exception& e)
{
   std::cout << e.what() << std::endl;
}    
于 2013-01-30T10:30:27.097 回答
1

您正在访问每个向量的边界之外:

std::vector<double> test1(1); // size 1 vector
test1[100] = 5.; // out of bounds access

结果是未定义的行为。如果要制作大小为 100 的向量,请执行以下操作:

std::vector<double> test1(101); // size 101 vector
test1[100] = 5.; // OK, access 101th element
test.push_back(42); // push element, size is now 102
于 2013-01-30T10:25:21.067 回答
0

如果您希望 operator[] 自动扩展/插入,请使用 std::map:

#include <iostream>
#include <map>

int main()
{
    std::map<double> test1;

    test1[100] = 5.; // Will insert one element into test1

    std::map< std::map <double > > test2;

    test2[50][100] = 5.; // will create a new map<double> and insert one element into it.
}
于 2013-01-30T11:32:14.167 回答