简体   繁体   中英

Seg fault vector<vector<list<Object*> > > push_back

I have a 3D vector defined like this...

std::vector<std::vector<std::list<Object*> > > m_objectTiles;

I have this code...

void ObjectManager::AddObject( Object *object ) {
  m_objects.push_back( object );
  m_objectTypes.insert( std::make_pair(
    ObjectAttorney::GetType( object ), object )); 

  int x = ObjectAttorney::GetTileX( object );
  int y = ObjectAttorney::GetTileY( object );
  m_objectTiles[x][y].push_back( object ); // SEG FAULT HERE
}

that receives this error 0x0805ccdb in std::vector<std::list<Object*, std::allocator<Object*> >, std::allocator<std::list<Object*, std::allocator<Object*> > > >::operator[] ( this=0x8157758, object=0x8173f30) at /usr/include/c++/4.4/bits/stl_vector.h:611 { return *(this->_M_impl._M_start + __n); } 0x0805ccdb in std::vector<std::list<Object*, std::allocator<Object*> >, std::allocator<std::list<Object*, std::allocator<Object*> > > >::operator[] ( this=0x8157758, object=0x8173f30) at /usr/include/c++/4.4/bits/stl_vector.h:611 { return *(this->_M_impl._M_start + __n); }

I changed it to this to test it...

void ObjectManager::AddObject( Object *object ) {
  m_objects.push_back( object );
  m_objectTypes.insert( std::make_pair(
    ObjectAttorney::GetType( object ), object )); 

  int x = ObjectAttorney::GetTileX( object );
  int y = ObjectAttorney::GetTileY( object );
  std::list<Object*> *l = &m_objectTiles[x][y];
  if ( l ) { // SEG FAULT HERE
    l->push_back( object );
  } else {
    std::cout << "List null.\n";
  }
}

which just gives an error message saying where the seg fault occured ObjectManager::AddObject (this=0x81577a0, object=0x8165760) at ObjectManager.cpp:381 if ( l ) {

Why would a seg fault occur when testing for a null pointer? Obviously operator [] is returning something corrupted or invalid. Not sure what the problem is here. Any help is appreciated. Thanks.

std::vector 's [] for performance reasons doesn't do range checks. Obviously that second variant doesn't help if x or y are out of range.

Add a check like that:

m_objectTiles.size() < x && m_objectTiles[x].size() < y

It is hard to judge from the quoted code, but it might be that you want std::vector to grow automatically. It will not. For that you would need something like that:

m_objectTiles.resize(x);
m_objectTiles[x].resize(y);

before accessing the m_objectTiles[x][y] .

The most probable cause for your problem is that ObjectAttorney::GetTileX and ObjectAttorney::GetTileY are returning out-of-range values, have you checked them?

The reason for the crash dump to indicate the if statement as the crash site is probably old debugging data, just rebuild your project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM