I wrote the following C++ code to iterate over a vector of vectors of objects. I want to iterate over every object in the vector of vectors. The code below works but it has one peculiarity I don't understand.
The line "int types_size=types->size();" is a hack employed in iterator.hpp. I don't really know the language very well so I don't know if I've found a compiler bug or if this a bug in my code. The variable "types_size" shouldn't be needed. It is used in two lines
first line:
while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&( ((*types)[s])->end()))){
second line:
if(s<types_size){
If "types_size" is replaced with "types->size()" in the first line the code will seg fault when it runs. Making the same replacement but only in the second line does not result in a seg fault. I don't understand what is going on. Any comments on the rest of this code will be appreciated.
#ifndef _iterator_hpp_
#define _iterator_hpp_
#include <vector>
using namespace std;
typedef double Object;
typedef vector<Object> ObjectVector;
class Region{
public:
vector<ObjectVector*> types;
};
class ObjectIterator{
private:
int s;
vector<ObjectVector*> *types;
protected:
public:
Object *object;
bool finished;
ObjectIterator operator++(){
if (s>=0) object++; // increments to next object
int types_size=types->size(); // this is a hack that fixes a seg fault (compiler bug??)
// *types is a vector<ObjectVector*>. (*types)[s] is the "sth" ObjectVector*.
// &(*iterator) gives a pointer to the object pointed to by iterator.
//((*types)[s])->end()) is an iterator that points past the end of
// the ObjectVector* ((*types)[s])->end())
while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&(* ((*types)[s])->end()))){
//need to increment to next non-empty types
s++;
if(s<types_size){
object=&((*(*types)[s])[0]);
}else{finished=true;}
}
return (*this);
}
/*---------------------constructor--------------------------------------------------------
start with s=-1 and increment to first object */
ObjectIterator(vector<ObjectVector*> *typesarg):finished(false) {
types=typesarg;s=-1;++(*this);
};
};
#endif
--------------------------------main--------------------------------
// it.cpp
// g++ it.pp
#include <iostream>
#include <vector>
#include "iterator.hpp"
using namespace std;
int num_types=3;
int main(){
Region region;
int num_objects[num_types];
num_objects[0]=1;
num_objects[1]=3;
num_objects[2]=5;
// create an ObjectList for each type
for(int s=0;s<num_types;s++){
ObjectVector *objectlist = new ObjectVector;
for(int i=0;i<num_objects[s];i++){
objectlist->push_back((double)2*(i+1)*(s+1));
}
region.types.push_back(objectlist);
}
cout <<"types.size="<< region.types.size()<<endl;
for(ObjectIterator OI(®ion.types); !OI.finished ; ++OI)
{
cout <<*(OI.object)<<endl;
}
}