矢量push_back访问冲突

时间:2010-10-01 14:48:30

标签: c++ stl vector 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导致访问冲突“OgreAR.exe中0x00471679处的未处理异常:0xC0000005:访问冲突读取位置0x00000018。”。

作为测试,我尝试了这个:

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

这很好用。

我做错了什么?!谢谢!

6 个答案:

答案 0 :(得分:6)

您调用TrackingSystem的{​​{1}}对象已经死亡(addMarker指针无效,可能很高。要么超出范围,要么过早删除调用,或从未正确创建(指针仍为空)。

这更有可能,因为对本地向量的push_back工作正常。

答案 1 :(得分: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() );

顺便说一下,将第三个参数作为const引用传递以避免不需要的副本可能会更好。

答案 2 :(得分:2)

抱歉,原来我是一个布偶。我在调用addMarker之前没有初始化我的TrackSystem实例。

道歉是浪费时间!

答案 3 :(得分:1)

只是为了调试,请尝试

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

然后使用调试器进入,看看发生了什么。可能是你在其他地方发生了内存损坏,当你进入这个函数调用时,这个TrackingSystem实例有一个损坏的mMarkers向量。

答案 4 :(得分:0)

这些只是基于所提供信息的猜测。

  1. MarkerData ctor不会初始化翻译或方向,因此会默认初始化它们。那够了吗? (顺便说一句,使用该ctor中的成员初始化列表而不是赋值。并通过const引用而不是通过值传递Matrix4对象。)

  2. ceretullis有一个很好的建议。如果您的代码已在问题中发布,那么您无法确定在构建临时MarkerData对象期间或在push_back调用期间是否发生了崩溃。

  3. 基于“访问冲突读取位置0x00000018”。这可能正在发生,因为有一个空指针在某处被解除引用。您没有显示足够的代码来查看空指针的位置,或者它可能位于Ogre库中的某个位置。

  4. 您的测试表明存在与堆栈相关的问题。在堆栈上声明向量而不是成员变量时,它会更改堆栈帧的布局。创建的临时MarkerData也在堆栈上创建。如果您没有遇到该测试的问题,可能是因为堆栈布局不同 - 可能在MarkerData的复制构造函数中存在一些缓冲区溢出,在您的示例中会被调用几次。 / p>

答案 5 :(得分:0)

您如何致电TrackingSystem::addMarker()

它是否通过NULL(或其他虚假的)TrackingSystem*