Under-the-hood STL: Concatenating an std::vector t

2019-07-16 14:14发布

问题:

This question already has an answer here:

  • Nice way to append a vector to itself 4 answers

I have an STL vector that stores the diagonals of a matrix. A certain mathematical rule I'm implementing tells me that I can produce a new matrix of a tensor product's diagonals simply by taking the original vector and concatenating a copy of that vector onto itself (it doubles in size, and the values repeat after 1/2 * size() ).

I wrote the following code:

std::vector<int> aVec;

for (int k = 0; k < aVec.size(); k++) aVec.insert(aVec.end(), aVec[k]);

But I get seg-faults when I try this. If I create a copy of aVec and use that as the insert "value", as well as using it for the size() in the loop args, it will work, but I must do both of these things (otherwise I will still get seg-faults).

Can anyone explain what's going on underneath that makes this implementation not work?

回答1:

You will copy items indefinitely. Note how many to copy up front:

size_t n = aVec.size();
for (int k = 0; k != n; ++k)
  aVec.push_back(aVec[k]);

While many C++ algorithms are better expressed using begin() and end() iterators, in this case your access via index is superior, because modifying the container might invalidate the iterators, but the element access will remain valid. You can, however, use reserve to avoid that invalidation:

aVec.reserve(2*aVec.size());
std::copy(aVec.begin(), aVec.end(), std::back_inserter(aVec));


回答2:

Use iterator-based operations:

vec.reserve(vec.size() * 2);
vec.insert(vec.end(), vec.begin(), vec.end());


回答3:

You should read the value of aVec.size() once before you start adding elements to aVec.



标签: c++ stl vector