views:

158

answers:

1

I'm making some mistake with my iterators, but I can't see it yet.

I have a Boost MultiIndex container, HostContainer hmap, whose elements are boost::shared_ptr to members of class Host. All the indices work on member functions of class Host. The third index is by Host::getHousehold(), where the household member variable is an int.

Below, I'm trying to iterate over the range of Hosts matching a particular household (int hhold2) and load the corresponding private member variable Host::id into an array. I'm getting an "Assertion failed: (px != 0), function operator->, file /Applications/boost_1_42_0/boost/smart_ptr/shared_ptr.hpp, line 418" error in runtime when the household size is 2. (I can't yet tell if it happens anytime the household size is 2, or if other conditions must be met.)

typedef multi_index_container<
  boost::shared_ptr< Host >,
  indexed_by< 
    hashed_unique< const_mem_fun<Host,int,&Host::getID> >, // 0 - ID index
    ordered_non_unique< const_mem_fun<Host,int,&Host::getAgeInY> >, // 1 - Age index
    ordered_non_unique< const_mem_fun<Host,int,&Host::getHousehold> > // 2 - Household index
    > // end indexed_by
  > HostContainer; 

typedef HostContainer::nth_index<2>::type HostsByHH;

// inside main()
int numFamily = hmap.get<2>().count( hhold2 );
int familyIDs[ numFamily ];
for ( int f = 0; f < numFamily; f++ ) {
  familyIDs[ f ] = 0;
}
int indID = 0;
int f = 0;
std::pair< HostsByHH::iterator, HostsByHH::iterator > pit = hmap.get<2>().equal_range( hhold2 );
cout << "\tNeed to update households of " << numFamily << " family members (including self) of host ID " << hid2 << endl;
while ( pit.first != pit.second ) {
   cout << "Pointing at new family member still in hhold " << (*(pit.first))->getHousehold() << "; " ;
  indID = (*(pit.first) )->getID();
  familyIDs[ f ] = indID;
  pit.first++;
  f++;
} 

What could make this code fail? The above snippet only runs when numFamily > 1. (Other suggestions and criticisms are welcome too.) Thank you in advance.


I replaced the while() loop with

for ( HostsByHH::iterator fit = pit.first; fit != pit.second; fit++ ) {
  cout << "Pointing at new family member still in hhold " << (*fit)->getHousehold() << "; " ;
  indID = (*fit )->getID();
  cout << "id=" << indID << endl;
  familyIDs[ f ] = indID;
  f++;
} 

This seems to work.

I don't quite understand how this is a fix or why the earlier error only occurred with households of size 2. Any insight would be very welcome.

+1  A: 
int numFamily = hmap.get<2>().count( hhold2 );
int familyIDs[ numFamily ];

How can this possibly work? This shouldn't even compile: you can't define an array with a variable number of elements, numFamily had to be a compile time constant or else you have to define familyIDs as

int *familyIDs= new int[ numFamily ];
Joaquín M López Muñoz
Wow, thanks for pointing this out. It amazingly compiles with gcc 4.2.1. I'm confused why.
Sarah
Does this solve the original problem?
Joaquín M López Muñoz