Vector push_back Access Violation

2

This is probably a silly error, but it's driving me nuts trying to fix it.

I have a struct:

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

And a class:

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

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

Now, in the addMarker method:

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

This push_back causes an access violation "Unhandled exception at 0x00471679 in OgreAR.exe: 0xC0000005: Access violation reading location 0x00000018.".

As a test, I tried this:

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

This works fine.

What am I doing wrong?! Thanks!

c++
stl
vector
push-back
asked on Stack Overflow Oct 1, 2010 by Jack • edited Oct 1, 2010 by Nate

6 Answers

7

Chances are high that the TrackingSystem object on which you're calling addMarker is dead (and that the this pointer is invalid. Either it went out of scope, delete was prematurely called, or it was never properly created (the pointer is still null).

This is even more likely since the push_back to a local vector works fine.

answered on Stack Overflow Oct 1, 2010 by Mark B
3

this typically could happen if you're doing something like

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() );

or even simpler

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

btw it might be better to pass the third argument as a const reference to avoid unneeded copies.

answered on Stack Overflow Oct 1, 2010 by stijn
2

Sorry, turns out I was being a muppet. My instance of TrackSystem was not initialised before calling addMarker.

Apologies for being a time waster!

answered on Stack Overflow Oct 1, 2010 by Jack
1

Just for debugging, try

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

Then get in there with the debugger and see what is going on. It could be that you have memory corruption happening somewhere else, and when you get into this function call this instance of TrackingSystem has a corrupted mMarkers vector.

answered on Stack Overflow Oct 1, 2010 by paxos1977
0

These are just guesses based on the information provided.

  1. The MarkerData ctor does not initialize translation or orientation, so they will be default initialized. Is that adequate? (By the way, use the member initialization list in that ctor instead of assignment. And pass that Matrix4 object by const reference instead of by value.)

  2. ceretullis has a good suggestion. With your code as posted in the question, you really can't be sure if the crash is happening during construction of the temporary MarkerData object or during the push_back call.

  3. Based on "Access violation reading location 0x00000018." That's probably happening because there is a null pointer being dereferenced somewhere. You haven't shown enough code to see where that null pointer could be, or perhaps it is somewhere in the Ogre library.

  4. Your test suggests that there is a problem related to the stack. When you declare the vector on the stack instead of as a member variable, it changes the layout of the stack frame. The temporary MarkerData that gets created is also created on the stack. If you don't have a problem with that test you did, it's probably because of the difference in stack layout -- perhaps there is some buffer overflow in the copy constructor of MarkerData, which would be called a few times in your example.

answered on Stack Overflow Oct 1, 2010 by Dan
0

How are you calling TrackingSystem::addMarker()?

By any chance is it through a NULL (or otherwise bogus) TrackingSystem*?

answered on Stack Overflow Oct 1, 2010 by Michael Burr

User contributions licensed under CC BY-SA 3.0