小心vector :: reserve?

时间:2012-01-31 09:18:39

标签: c++ vector

我试图做这样的事情:

#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吗?

4 个答案:

答案 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::resizevector::erase,它们会修改矢量大小和内容)。

答案 3 :(得分:1)

除了其他答案之外,您不需要reservecopy,因为assign就足够了:

int main()
{
    int l[] = {1,2,3,4};
    vector<int> vi;
    vi.assign(l, l + 4); 

    do_stuff();
}