tags:

views:

91

answers:

3

I have a problem with a random crash caused by CSceneNode* pRoot = nodes[0]; // The real problem is = nodes[0]; Crash message is: The instruction at "0x0059d383" referenced memory at "0x00000000". The memory cound not be "read". I do not see the problem, could please help me out ?

In Save.cpp

void CNESave::SaveLocation(CNELocation* pLoc)
// Other code

    CSceneNode* scene = pLoc->GetScene();
    vector<CSceneNode*> nodes;          
    scene->GetNodes(GetNodesByPartOfName, nodes, &string("_Ldynamic"));
    CSceneNode* pRoot = nodes[0];   //This is the problem causing random crashes!
        // If I change it (just for testing) to CSceneNode* pRoot = scene 
        // them it isn't crashing.
        // So CSceneNode* pRoot is OK and the problematic part is = nodes[0];

In SceneNode.cpp

bool GetNodesByPartOfName(CSceneNode* node, const void *data)
{
    string *str = (string *)data;
    return node->GetName().find(*str)!=npos;
}

void CSceneNode::GetNodes( GetNodesFunc gf, vector<CSceneNode*> &nodes, 
   const void *data)
{
    if (gf(this, data)) nodes.push_back(this);
    SceneNodeIterator begin=FirstChild(), end=LastChild();
    for (;begin!=end;begin++) ((CSceneNode*)*begin)->GetNodes(gf, nodes, data);
}

CSceneNode* CSceneNode::CreateNew() 
{
    return new CSceneNode();
}

// a lot of other code

In SceneNode.h

class EXPORTDECL CSceneNode;
typedef bool (*GetNodesFunc)(CSceneNode *node, const void *data);
EXPORTDECL bool GetNodesByPartOfName(CSceneNode* node, const void *data);
typedef vector<CSceneNode*>::iterator SceneNodeIterator;
class EXPORTDECL CSceneNode : public CTreeNode<CSceneNode, true>  
{
public:
//construction & destruction
    CSceneNode();
    virtual ~CSceneNode();
    virtual CSceneNode *CreateNew();
// a lot of other code

Solved. Thank you guys very much.

+1  A: 

try using :

CSceneNode* pRoot = nodes.at(0);

If you get an exception, then you know something is wrong. Maybe your filter is too restrictive or you don't have child so nothing is returned.

You shouldn't use nodes[i] if you aren't 100% sure that the i index is valid.

BatchyX
+1  A: 

If the result of node->GetName() does not contain the string _Ldynamic, this will crash.

Because in this case GetNodesByPartOfName(..) will return false and GetNodes(..) will not execute nodes.push_back(this) and you will be left with an empty vector and later will try to access the first element of this empty vector after returning from GetNodes(..).

Andre Holzner
Thank you. How do I find out that an vector is empty in C++ (I am sorry for this question but I am so familiar with c++)
en667
`vector` has a method `empty()` (see http://www.sgi.com/tech/stl/Vector.html ).
Andre Holzner
+1  A: 

What you want to do is make sure the vector isn't empty:

CSceneNode *const pRoot = nodes.empty() ? NULL : nodes[0];
if (pRoot != NULL)
{
    // Do something...
}
Mark Ingram