我有一个代码,我用integer
值填充向量,并将其推送到指向向量的指针向量,如下所示:
std::vector<std::vector<int>*> set_of_vectors;
for(int i = 0; i < 10; i++)
{
//initialize vector
std::vector<int> pos_vector;
//fill it with 0s
pos_vector.resize(10, 0);
//fill it with integers
fill_vector(pos_vector);
//push into set_of_vectors
set_of_vectors.push_back(&pos_vector);
}
问题是输出真的很奇怪。输出应该等于
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
但相反,我得到以下输出:
9617952, 0, 2, 3, 4, 5, 6, 7, 8, 9,
#include <vector>
#include <iostream>
void fill_vector(std::vector<int> & values);
int main()
{
std::vector<std::vector<int>*> set_of_vectors;
for(int i = 0; i < 5; i++)
{
std::vector<int> pos_vector;
pos_vector.resize(10, 0);
fill_vector(pos_vector);
set_of_vectors.push_back(&pos_vector);
}
for(auto & vec:set_of_vectors)
{
for(auto &v:*vec)
{
std::cout << v <<", ";
}
std::cout << std::endl;
}
return 0;
}
void fill_vector(std::vector<int> & values)
{
for(int i = 0; i < values.size(); i++)
{
values[i] = i;
}
}
答案 0 :(得分:4)
这是UB。
pos_vector
是一个局部变量,当离开for
循环时将被销毁,然后推入向量的指针(即&pos_vector
)将是一个悬空指针,任何顺序在它上面是UB。
如果必须使用std::vector<std::vector<int>*>
,则需要new
指针:
for(int i = 0; i < 5; i++)
{
std::vector<int>* pos_vector = new std::vector<int>;
pos_vector->resize(10, 0);
fill_vector(*pos_vector);
set_of_vectors.push_back(pos_vector);
}
最后不要忘记delete
。
答案 1 :(得分:3)
您正在添加指向本地对象的指针。这些本地对象将在每个for循环结束时被销毁,并且你保持一个带有指针指向垃圾的向量(&#34;悬空指针&#34;)。
您可以定义std::vector<std::vector<int>> set_of_vectors
并使用&set_of_vectors[idx]
获取每个元素的指针。
以下代码从向量列表中创建指针列表,并可在库调用中使用:
std::vector<std::vector<int>*> set_of_ptrs;
set_of_ptrs.reserve(set_of_vectors.size());
for(auto& v: set_of_vectors)
set_of_ptrs.push_back(&v);
答案 2 :(得分:1)
您必须执行类似
的操作for(int i = 0; i < 5; i++)
{
std::vector<int>* pos_vector = new std::vector<int>();
pos_vector->resize(10, 0);
fill_vector(*pos_vector);
set_of_vectors.push_back(pos_vector);
}
您的示例会为您分配堆栈中分配的pos_vector
地址的悬空指针。
答案 3 :(得分:0)
您必须将向量复制到数组中,pos_vector
是一个局部变量,存储其引用将导致未定义的行为,因为向量一旦超出范围就会被删除。您还应将set_of_vectors
定义为类型std::vector
的{{1}}而不是std::vector<int>
,因为您不希望存储超出范围的指针。
std::vector<int>*
借助#include <vector>
#include <iostream>
void fill_vector(std::vector<int>& values)
{
for(int i=0; i<values.size(); ++i)
values[i] = i;
}
int main()
{
std::vector<std::vector<int>> set_of_vectors;
for(int i = 0; i<5; ++i)
{
std::vector<int> pos_vector;
pos_vector.resize(10, 0);
fill_vector(pos_vector);
set_of_vectors.push_back(pos_vector);
}
for(auto& vec : set_of_vectors)
{
for(auto& v : vec)
{
std::cout << v <<", ";
}
std::cout << std::endl;
}
return 0;
}
功能,您可以大大简化作业。
std::iota