我试图做这样的事情:
#include <vector>
#include <algorithm>
int main()
{
int l[] = {1,2,3,4};
vector<int> vi(4);
copy(l, l+4, vi.begin());
do_stuff();
}
上面的代码可以编译运行,没有错误。然后我把它变成了这个:
int main()
{
int l[] = {1,2,3,4};
vector<int> vi;
vi.reserve(4); //different from the above code
copy(l, l+4, vi.begin());
do_stuff();
}
根据代码,我将vector<int> vi(4);
更改为vector<int> vi; vi.reserve(4);
,但问题来了,也就是说,更改的代码可以编译,但是当发生seg-fault时会发生它运行。
根据gdb
,seg-fault出现在函数do_stuff();
中。
为什么?我做出的改变是否重要?我不能在这里使用reserve
吗?
答案 0 :(得分:9)
reserve()
方法仅分配内存,但保留未初始化状态。它仅影响capacity()
,但size()
将保持不变。
如果要创建任意数量的实例,则应使用分配内存的resize()
,并创建与传递给resize()
的参数一样多的实例。
答案 1 :(得分:3)
在我看来,您实际想要实现的是使用元素列表初始化向量。使用新的列表初始化语法在C ++ 11中很容易实现这一点:
std::vector<int> vi {1, 2, 3, 4};
如果你的编译器还不支持这种语法,你可以使用旧的范围构造函数:
int a[] = {1, 2, 3, 4};
std::vector<int> vi(a + 0, a + 4);
如果由于某种原因你真的想要保留空间然后再推回元素,请写下:
std::vector<int> vi;
vi.reserve(4);
int a[] = {1, 2, 3, 4};
std::copy(a + 0, a + 4, std::back_inserter(vi)); // need to #include <iterator>
答案 2 :(得分:1)
来自一个特定的C++ reference:
在任何情况下,对[vector :: reserve]的调用都不会影响向量中包含的元素,也不会影响向量大小(为此目的,请参阅vector::resize或vector::erase,它们会修改矢量大小和内容)。
答案 3 :(得分:1)
除了其他答案之外,您不需要reserve
和copy
,因为assign
就足够了:
int main()
{
int l[] = {1,2,3,4};
vector<int> vi;
vi.assign(l, l + 4);
do_stuff();
}