Вектор ошибки сегмента <vector <list <Object *>>> push_back - PullRequest
0 голосов
/ 24 июля 2010

У меня есть трехмерный вектор, определенный следующим образом ...

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

У меня есть этот код ...

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
}

, который получает эту ошибку 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); }

Я изменил это на это, чтобы проверить это ...

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";
  }
}

, которое просто выдает сообщение об ошибке, сообщающее, где произошла ошибка сегмента ObjectManager::AddObject (this=0x81577a0, object=0x8165760) at ObjectManager.cpp:381 if ( l ) {

Почему ошибка сегмента возникает, когдатестирование на нулевой указатель?Очевидно, оператор [] возвращает что-то поврежденное или недействительное.Не уверен, что проблема здесь.Любая помощь приветствуется.Спасибо.

Ответы [ 2 ]

2 голосов
/ 24 июля 2010

std::vector [] по соображениям производительности не выполняет проверки диапазона.Очевидно, что второй вариант не помогает, если x или y находятся за пределами диапазона.

Добавьте проверку следующим образом:

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

Трудно судить по приведеннымкод, но может случиться так, что вы хотите, чтобы std :: vector рос автоматически.Я не буду.Для этого вам понадобится что-то вроде этого:

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

до доступа к m_objectTiles[x][y].

1 голос
/ 24 июля 2010

Наиболее вероятная причина вашей проблемы заключается в том, что ObjectAttorney :: GetTileX и ObjectAttorney :: GetTileY возвращают значения вне диапазона, проверяли ли вы их?

Причиной аварийного дампа для указанияЕсли утверждение, что сайт аварийного отказа, вероятно, старые отладочные данные, просто пересоберите ваш проект.

...