2010-07-24 3 views
0

У меня есть 3D-вектор, определенный как это ...Seg вектор вина <вектор <список <Object*>>> push_back

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) {

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

+3

В качестве отправной точки вы можете заменить 'std :: vector >>' с несколькими инкапсулирующими классами ... –

ответ

2

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

Добавить чек так:

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

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

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

перед доступом к m_objectTiles[x][y].

+0

На самом деле это делается за пределами указанного кода (вектор имеет размер до определенного размера при построении, и GetTileX и GetTileY гарантированно возвращают координаты в границах). – random

+0

Это действительно заставило меня подумать, что изменение размера было выполнено слишком рано в создании ObjectManager. Не вдаваться в подробности, но это привело к решению проблемы. Благодарю. – random

1

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

Причина появления аварийного дампа для указания инструкции if в качестве места сбоя, вероятно, является старой отладочной информацией, просто перестройте свой проект.

Смежные вопросы