Search code examples
c++98mbed

How do I correctly copy given range of vector to another vector using std::copy?


I found a few pages on moving vector range to another vector, however I am struggling to make it work.

I would like to move elements from sourceVect to destVect, with the elements between sourceVect[1] to sourceVect[1+numToCopy] being moved to the beginning of sourceVect. I tried to do this in the following way:

vector<int> destVect;
vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
int numToCopy = 7;

vector<int>::iterator itSource = sourceVect.begin();
vector<int>::iterator itSourceEnd = sourceVect.begin();
advance(itSource, 1);
advance(itSourceEnd, 1+numToCopy);

std::copy(itSource, itSourceEnd, destVect.begin());             //copy(first,last,output vector ite)


for (vector<int>::iterator it = destVect.begin(); it != destVect.end(); ++it)
    cout << ' ' << *it;

But I am getting Debug Assertion Failed, vector iterator + offset out of range in Visual studio. Please note that I am only trying it out in Visual Studio 2015, it has to be implemented in C++98 for mbed at the end, meaning I can't use std::next for example.


Solution

  • std::copy() will not create new elements in the destination container. That means you need to create destVect with the correct size:

    vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    vector<int> destVect(sourceVect.size() - 1);
    

    If you can't create it with the correct size, just resize it later on, at the point where you know the size:

    destVect.resize(sourceVect.size() - 1);
    

    You can now copy:

    copy(sourceVect.begin() + 1, sourceVect.end(), destVect.begin());
    

    However, you can just create destVect with the correct contents to begin with. You don't need to manually copy anything:

    vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    vector<int> destVect(sourceVect.begin() + 1, sourceVect.end());
    

    This is the fastest way to do this and (perhaps more importantly) it's not prone to errors. If you do an std::copy but your destination container's size is not large enough, you end up writing into non-allocated memory (buffer overflow.)