Be careful of vector::reserve?

2019-07-02 09:19发布

问题:

I was trying to do something like this:

#include <vector>
#include <algorithm>

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

    do_stuff();
}

The above code can compile and run without no errors. Then I changed it into this:

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();
}

According to the code, I changed vector<int> vi(4); into vector<int> vi; vi.reserve(4);, but the problem comes, that is, the changed code can compile, but a seg-fault occurs when it runs.

According to gdb, the seg-fault occurs in function do_stuff();.

Why is that? Does the change I made matter? Can't I use reserve here?

回答1:

The reserve() method only allocates memory, but leaves it uninitialized. It only affects capacity(), but size() will be unchanged.

If you want to create as many instances you should use resize() which allocates memory, and also creates as many instances as the argument passed to resize().



回答2:

It appears to me that what you actually want to achieve is initialize a vector with a list of elements. This is easily achieved in C++11 with the new list-initialization syntax:

std::vector<int> vi {1, 2, 3, 4};

If your compiler does not support this syntax yet, you can use the good old range constructor:

int a[] = {1, 2, 3, 4};
std::vector<int> vi(a + 0, a + 4);

If for some reason you really want to reserve space and then push the elements back later, write this:

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>


回答3:

In addition to other answers, you don't need reserve and copy, because assign is sufficient here:

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

    do_stuff();
}


回答4:

From one particular C++ reference:

In any case, a call to [vector::reserve] never affects the elements contained in the vector, nor the vector size (for that purposes, see vector::resize or vector::erase, which modify the vector size and content).



标签: c++ vector