我有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
答案 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.assign和C++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)
我发现了问题。它在功能上处理矢量的大小。显然,矢量是空的。愚蠢的错误。谢谢大家的答案。