dirty little vectors and why they don't want to stay together

Sep 16, 2015 at 1:34pm
Hey, the basic idea is to concatanate two vectors in a big one.
Unfortunately I get the error:
terminate called after throwing an instance of 'std::length_error'
what(): vector::_M_range_insert

the Idea is to create one big vector in ChildB collector which contains the vector vec of ChildA child1 and child2.
Here I have written the code snippet:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Base{
public:
inline std::vector<double> getVec(){return this->vec;};
inline unsigned getVecDimension(){return this->vec.size();};
protected:
std::vector<double> vec;
}

class ChildA:Base{
ChildA(std::vector<double> vecinit){vec=vecinit;}
}

class ChildB:Base{
protected:
   std::vector<Base*> childlist;
public:
ChildB(std::vector<Base*> listofChildren){
   childlist=listofChildren;
   for(int i=0;i<this->childlist.size();i++){
//HERE WE GET THE ERROR!!! 
//terminate called after throwing an instance of 'std::length_error'
//  what():  vector::_M_range_insert
   //this->vec.size()=0
      this->vec.insert(this->vec.end(), childlist[i][0].getVec().begin(), childlist[i][0].getvec().end());
   //this->vec.size()=2940?????
   }
}

int main(){
std::vector<double> init1 (4,1); //4 Elements=1
std::vector<double> init2 (4,2); //4 Elements=2
ChildA child1(init1);
ChildA child2 (init2);
std::vector<Base*> childlist (2);
childlist[0]=&child1;
childlist[1]=&child2;
ChildB collector (childlist);

}


Any ideas why the size is changing suddenly to that strange number and whats the problem?
The compilation runs without warnings, but the running crashes.
Also with debugging I can't find the issue.
Thank you very much for helping
Last edited on Sep 16, 2015 at 1:36pm
Sep 16, 2015 at 2:12pm
std::vector<double> getVec()
returns a temporary copy of vec.
Different calls to getVec results in different copies being made.

So in line vec.insert(this->vec.end(), childlist[i][0].getVec().begin(), childlist[i][0].getvec().end()); childlist[i][0].getVec().begin() and childlist[i][0].getVec().end() returns iterators to different vectors, causing undefined behavior.
Sep 16, 2015 at 2:17pm
Wondering how you could determine the error since you code is riddled with compiler errors.

However. The problem is this: childlist[i][0].getVec().begin(). The insert function expects a valid iterator.

if vec of the child elment is empty (like in your case) the iterator is invalid and that leads to undefined behavior.

So before line 24 you need an if that prevents the insertion when childlist[i][0].getVec().empty().


By the way: Why not childlist[i]->getVec()?
Sep 16, 2015 at 2:40pm
Thank you very much. You both are right!
Returning a vector iterator for begin and end, or storing the vector in a dummy variable, solves the problem.
Returning the iterator seems to be a bit dirty, but takes half of the time than copying it (even worse for bigger vectors).
Last edited on Sep 16, 2015 at 2:41pm
Topic archived. No new replies allowed.