2013-07-04 57 views
-3

为什么我得到“分割故障(核心转储)”,当我这样做:分配对在C++的矢量

std::vector<std::pair<int,int> > hm; 
hm[0] = pair<int,int> (1,1); 
+5

越界访问 - >未定义的行为。你的矢量是空的,你试图访问第一个元素。 –

+4

尝试使用相同的代码,但要简化它 - 仅使用“int”而不是“pair”。你有相同的结果吗?如果是这样,这个问题不太可能与'pair's参与的事实有关: –

+0

要添加到Andy的评论中,请使用'push_back'或'emplace_back'而不是下标运算符。 – syam

回答

1

这个向量的初始大小为0,operator[]不检查范围。你需要使用push_back方法(它会自动为你增加一个向量的大小,而我的意思是元素的数量),或者给这个向量初始化一个构造函数重载的大小,如下所示:

std::vector<std::pair<int, int>> hm(5); 

或与resize方法。

+0

调整大小是我一直在寻找的!谢谢 –

5

载体不包含的元素与零的索引,它只是空。您应该添加一个新项目:

hm.push_back(pair<int,int>(1,1)); 
+2

并使用'std :: make_pair()',可能是 –

+1

或者:'hm.emplace_back(1,1);' –

+0

是的,但是如果我想添加到某个位置? –

0

当你写

std::vector<std::pair<int,int> > hm; 

要创建载体,它,它不包含任何元素。在下一行,

hm[0] = std::pair<int,int> (1,1); 

你想分配给该向量无元素,这是不确定的行为的第一个元素(和你的系统上发生造成分段错误,至少在案件你试过了)。如果你想赶上在运行时这样的错误,你可以使用at,如

hm.at(0) = std::pair<int,int> (1,1); 

但是你得到这样的唯一的事情是个例外,而不是不确定的行为,它不解决根本问题,即你访问一个根本不存在的对象。

现在有几种方法来创建对象:

首先,你可以“按需”与push_back创建它:

hm.push_back(std::pair<int,int> (1,1)); 

这使得向量在最后追加的对象(因为矢量最初是空的,所以这是之后唯一的元素,因此它是hm[0],并用你传递给push_back的值初始化它。

另一种方法是给矢量元素从一开始:

std::vector<std::pair<int,int> > hm(1); 
hm[0] = std::pair<int,int> (1,1); 

这里的构造参数告诉向量立即创建(和默认初始化)一个元素。由于现在有第一个元素,您可以毫无问题地分配给它。但是请注意,默认初始化会花费一点性能,并且可能不适用于某些类型。

在特定的情况下,还可以观察到,所有的元素都相等(因为只有一个),因此,你可以使用这两个参数的构造函数在这里:

std::vector<std::pair<int,int> > hm(1, std::pair<int,int> (1,1)); 

在一个不相关的注意:不能std::pair<int, int>您可以使用std::make_pair并保存自己明确提及的类型。

0

如果您确实想让[]的行为与Python和Ruby中的行为类似,那么在hm[i] = j之前会使用if (hm.size() < i+1) { hm.resize(i+1); }