C ++访问向量

时间:2010-11-22 15:34:32

标签: c++ vector std

我有std::vector,其中包含我自己的类,我必须访问它的函数和空白。

class A
{
private: 
     int var;
     vector<string> vec;

public:
     void setVar(int i) { var = i; }
     void setVec(vector<string> a) { vec = a; }
};

我还返回了函数,但我没有打扰它们。我已经包含了所有必要的文件。

int main()
{
    vector<A> vec;
    for (int i = 0; i < 10; i++)
    {
        A tmp;
        tmp.setVar(i);
        vec.push_back(tmp);
    }

    for (int i = 0; i < 10; i++)
    {
        vector<string> tmp;
        tmp.push_back("1");
        tmp.push_back("2");
        tmp.push_back("3");
        vec.at(i).setVec(tmp);  //Works sometimes or causes error std::out_of_range
        vec[i].setVec(tmp);     //Crashes the whole programm
    }
}

那么如何在vector初始化之后设置这些变量?

我使用的是g ++,这不是真正的代码,因为我的实际代码很乱。

Error for vec.at(i).setVec(tmp);
Error is:  terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check

4 个答案:

答案 0 :(得分:2)

您使用的是哪种编译器?我真的很惊讶std::vector<std::string> tmp("1","2","3");甚至编译!

说实话,我不知道它叫什么,但我敢打赌,它不符合你的期望,我相信是:

std::vector<std::string> tmp;
tmp.push_back("1");
tmp.push_back("2");
tmp.push_back("3");

对于记录,boost.assignC++0x提供了您尝试实现的容器初始化。

答案 1 :(得分:2)

您发布的代码仍然无法编译(在第一个循环中没有声明tmp),所以让我解释一下会发生什么。

您提到了两种错误:

vec.at(i).setVec(tmp);  //Works sometimes or causes error std::out_of_range

函数at试图安全 - 它首先检查向量的长度,然后返回给定索引的元素,如果向量不包含元素,则抛出std::out_of_range这样的指数。

第二种情况:

vec[i].setVec(tmp);     //Crashes the whole programm

运算符[]的行为与向量的at()函数非常相似,但它不“安全”,因为它不执行任何边界检查。因此,如果您尝试访问3元素的第4个元素,您只需访问内存中的某个随机位置(例如,可能是另一个不相关的变量,可能是其他任何内容)。如果你很幸运,你的程序将在此之后崩溃。如果你运气不好,你会遇到内存损坏问题和非常奇怪的错误,很难找到。

您的问题的解决方案是:

a)将vec[i]替换为vec.at(i) - 工作相同(好吧,一点点更慢,但你不会感觉到这一点)并且你是安全的。

b)然后:当你实际进行矢量查找时,查看所有地方,并在每个地方停一秒钟并考虑:“此时此向量有多大?我确定该索引的元素存在?”。

你可能很快就会发现你的错误。

答案 2 :(得分:1)

我在VS2010中尝试了您的代码,但无法重现您描述的问题。当然,按值传递矢量不是一个好主意,它应该是对常量的引用,但它不能导致这样的错误。考虑到'std :: out_of_range'被引发的事实,最可能的原因是你的向量中没有带有这种索引的元素。对于测试,您可以在访问i < vec.size()(或vec[i])之前检查vec.at(i)是否

答案 3 :(得分:0)

我发现了问题。它在功能上处理矢量的大小。显然,矢量是空的。愚蠢的错误。谢谢大家的答案。