2010-10-01 3 views
1

Это, вероятно, глупая ошибка, но это заставляет меня гайки пытаться ее исправить.Вектор push_back Нарушение прав доступа

У меня есть-структуру:

struct MarkerData 
{ 
int pattId; 
unsigned short boneId; 
Ogre::Matrix4 transToBone; 
Ogre::Vector3 translation; 
Ogre::Quaternion orientation; 

MarkerData(int p_id, unsigned short b_id, Ogre::Matrix4 trans) 
{ 
    pattId = p_id; 
    boneId = b_id; 
    transToBone = trans; 
} 
}; 

и класс:

class TrackingSystem 
{ 
public: 
    void addMarker(int pattId, unsigned short boneId, Ogre::Matrix4 transToBone); 

private: 
    std::vector <MarkerData> mMarkers; 
}; 

Теперь в методе addMarker:

void TrackingSystem::addMarker(int pattId, unsigned short boneId, Ogre::Matrix4 transToBone) 
{ 
    mMarkers.push_back(MarkerData(pattId,boneId,transToBone)); 
} 

Это push_back вызывает нарушение прав доступа «Необработанное исключение на 0x00471679 в OgreAR.exe: 0xC0000005: место чтения нарушения доступа 0x00000018. ".

В качестве теста, я попытался это:

void TrackingSystem::addMarker(int pattId, unsigned short boneId, Ogre::Matrix4 transToBone) 
    { 
     std::vector <MarkerData> test; 
     test.push_back(MarkerData(pattId,boneId,transToBone)); 
    } 

Это прекрасно работает.

Что я делаю неправильно ?! Благодаря!

+0

Можете ли вы поймать исключение и выяснить, что это такое? Это может привести к правильному ответу. – Starkey

ответ

6

Шансы высоки, что TrackingSystem объекта, на котором вы вызываете addMarker мертв (и что this указателя является недействительным. Либо он вышел из рамки, удалять преждевременно назвать, или он никогда не был должным образом создан (указатель по-прежнему нулевой).

Это еще более вероятно, так как push_back в местный вектор работает отлично.

1

Только для отладки, попробуйте

void TrackingSystem::addMarker(int pattId, unsigned short boneId, Ogre::Matrix4 transToBone) 
{ 
    MarketData m(pattId, boneId, transToBone); 
    mMarkers.push_back(m); 
} 

Тогда попасть туда с отладчиком и посмотреть, что происходит. Возможно, у вас есть коррупция памяти, происходящая где-то в другом месте, и когда вы включаетесь в эту функцию, этот экземпляр TrackingSystem имеет поврежденный вектор mMarkers.

+0

Спасибо за помощь! Просто глядя в отладчик и значение «это», когда в addMarker равно 0. Это нехорошо? – Jack

3

обычно это может произойти, если вы делаете что-то вроде

TrackingSystem* p = new TrackingSystem(); 
delete p; //or p = 0, or anything that makes p not point to the object anymore 
p->AddMarker(0, 0, Ogre::Matrix4()); 

или еще проще

TrackingSystem* p; 
p->AddMarker(0, 0, Ogre::Matrix4()); 

Кстати, было бы лучше передать третий аргумент в качестве константной ссылке, чтобы избежать ненужных копий ,

0

Это только предположения, основанные на информации.

  1. MarkerData ctor не инициализирует перевод или ориентацию, поэтому они будут инициализированы по умолчанию. Это адекватно? (Кстати, используйте список инициализации члена в этом ctor вместо назначения. И передайте этот объект Matrix4 по константной ссылке вместо значения.)

  2. У ceretullis есть хорошее предложение. С вашим кодом, опубликованным в вопросе, вы действительно не можете быть уверены, что произошел сбой во время создания временного объекта MarkerData или во время вызова push_back.

  3. Основано на «Доступном месте обнаружения нарушения доступа 0x00000018». Вероятно, это происходит потому, что где-то существует нулевой указатель.Вы не указали достаточно кода, чтобы увидеть, где может быть этот нулевой указатель, или, возможно, он находится где-то в библиотеке Ogre.

  4. Ваш тест показывает, что существует проблема, связанная с стеком. Когда вы объявляете вектор в стеке вместо переменной-члена, он меняет макет фрейма стека. Временная MarkerData, которая создается, также создается в стеке. Если у вас нет проблемы с этим тестом, вы, вероятно, из-за разницы в компоновке стека - возможно, в конструкторе копирования MarkerData есть избыток буфера, который будет называться несколько раз в вашем примере.

0

Как вы называете TrackingSystem::addMarker()?

Возможно ли это через NULL (или иначе фиктивный) TrackingSystem*?

2

Извините, оказывается, я был маппетом. Мой экземпляр TrackSystem не был инициализирован перед вызовом addMarker.

Извинения за то, что вы теряете время!

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