No errors or warnings but still crashes

Stuck for days....My program compiles without any warnings or errors. however it crashes straight away and doesn't give a reason. If I debug it I get these messages. Has anybody came across similar messages?

#0 00431CDC TiXmlNode::FirstChild(this=0x0) (C:/Users/Home/Code/SDL_GameDev - FrameWork - Copy/tinyxml.h:521)
#1 00407AFF TiXmlNode::FirstChildElement(this=0x0) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy\tinyxml.cpp:456)
#2 0042F623 TiXmlNode::FirstChildElement(this=0x0) (C:/Users/Home/Code/SDL_GameDev - FrameWork - Copy - Copy/tinyxml.h:665)
#3 00405F56 StateParser::parseTextures(this=0x28fcc4, pStateRoot=0x0, pTextureIDs=0x3b3e3c) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy - Copy\StateParser.cpp:75)
#4 00405D0C StateParser::parseState(this=0x28fcc4, stateFile=0x4882ad "test.xml", stateID=..., pObjects=0x3b3e58, pTextureIDs=0x3b3e3c) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy - Copy\StateParser.cpp:51)
#5 0040399E MainMenuState::onEnter(this=0x3b3e38) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy - Copy\MainMenuState.cpp:54)
#6 004023FC GameStateMachine::changeState(this=0x3b3e10, pState=0x3b3e38) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy\GameStateMachine.cpp:39)
#7 004017F1 Game::init(this=0x3b2e68, title=0x488253 "Joe", xpos=100, ypos=100, width=640, height=480, fullscreen=false) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy - Copy\Game.cpp:48)
#8 00403621 SDL_main(argc=argc@entry=1, argv=argv@entry=0x3a0008) (C:\Users\Home\Code\SDL_GameDev - FrameWork - Copy - Copy\main.cpp:11)
#9 0040E77C console_main(argc=argc@entry=1, argv=argv@entry=0x3a0008) (../src/main/windows/SDL_windows_main.c:140)
#10 0040E93D WinMain@16(hInst=0x400000, hPrev=0x0, szCmdLine=0xad43ab "", sw=10) (../src/main/windows/SDL_windows_main.c:177)
#11 0048436B main () (??:??)

Here's some of the code that might be broken from those files, the tiny xml stuff should be ok as I never created it and is too large to list here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "StateParser.h"
#include "TextureManager.h"
#include "Game.h"
#include "GameObjectFactory.h"

bool StateParser::parseState(const char* stateFile, std::string stateID,
                             std::vector<GameObject*> *pObjects,
                             std::vector<std::string> *pTextureIDs)
{
    // create the XML document
    TiXmlDocument xmlDoc;

    // load state file
    if(!xmlDoc.LoadFile(stateFile))
    {
        std::cerr << xmlDoc.ErrorDesc() << "\n";
        return false;
    }

    // get the root element
    TiXmlElement* pRoot = xmlDoc.RootElement();

    // pre declare the states root mode
    TiXmlElement* pStateRoot = 0;

    // get this states root node and assign it to pStateRoot
    for(TiXmlElement* e = pRoot->FirstChildElement(); e != NULL;
        e = e->NextSiblingElement())
    {
        if(e->Value() == stateID)
        {
            pStateRoot = e;
            break;
        }
    }

    // pre-declare the texture root
    TiXmlElement* pTextureRoot = 0;

    for(TiXmlElement* e = pStateRoot->FirstChildElement(); e != NULL;
        e = e->NextSiblingElement())
    {
        if(e->Value() == std::string("TEXTURES"))
        {
            pStateRoot = e;
            break;
        }
    }

    // now parse the textures
    parseTextures(pTextureRoot, pTextureIDs);

    // pre declare the object root node
    TiXmlElement* pObjectRoot = 0;

    // get the root node and assign it to pObjectRoot
    for(TiXmlElement* e = pStateRoot->FirstChildElement(); e != NULL;
    e = e->NextSiblingElement())
    {
        if(e->Value() == std::string("OBJECTS"))
        {
            pObjectRoot = e;
            break;
        }
    }

    // now parse the objects
    parseObjects(pObjectRoot, pObjects);

    return true;
}

void StateParser::parseTextures(TiXmlElement* pStateRoot, std::vector<std::string>* pTextureIDs)
{
    for(TiXmlElement* e = pStateRoot->FirstChildElement(); e != NULL;
    e = e->NextSiblingElement())
    {
        std::string filenameAttribute = e->Attribute("filename");
        std::string idAttribute = e->Attribute("ID");
        pTextureIDs->push_back(idAttribute); // push into list

        theTextureManager::Instance()->load(filenameAttribute,
                    idAttribute, theGame::Instance()->getRenderer());
    }
}


void StateParser::parseObjects(TiXmlElement* pStateRoot, std::vector<GameObject*> *pObjects)
{
    for(TiXmlElement* e = pStateRoot->FirstChildElement(); e != NULL;
    e = e->NextSiblingElement())
    {
        int x, y, width, height, numFrames, callBackID, animSpeed;
        std::string textureID;

        e->Attribute("x", &x);
        e->Attribute("y", &y);
        e->Attribute("width", &width);
        e->Attribute("height", &height);
        e->Attribute("numFrames", &numFrames);
        e->Attribute("callBackID", &callBackID);
        e->Attribute("animSpeed", &animSpeed);

        textureID = e->Attribute("textureID");

        GameObject* pGameObject = TheGameObjectFactory::Instance()
        ->create(e->Attribute("type"));

        pGameObject->Load(new LoaderParams
        (x, y, width, height, textureID, numFrames, callBackID, animSpeed));

        pObjects->push_back(pGameObject);
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "MainMenuState.h"

const std::string MainMenuState::s_menuID = "MENU";

void MainMenuState::update()
{
    for(unsigned i = 0; i < m_gameObjects.size(); i++)
    {
        m_gameObjects[i]->update();
    }
    //Check and deque the state if its invalid
    //theGame::Instance()->getStateMachine()->dequeState();
// work around
  /*  int cObjects = m_gameObjects.size();

    for(int i = 0; i < cObjects; i++){
        if(cObjects == m_gameObjects.size()){
            m_gameObjects[i]->update();
        }
    }*/
}

void MainMenuState::render()
{
    for(unsigned i = 0; i < m_gameObjects.size(); i++)
    {
        m_gameObjects[i]->draw();
    }
}


void MainMenuState::setCallBacks(const std::vector<CallBack>& callBack)
{
    // go through the game objects
    if(!m_gameObjects.empty())
    {
        for(unsigned int i = 0; i < m_gameObjects.size(); i++)
        {
            // if they are of type MenuButton then assign a callback based on the id passed in from the file
            if(dynamic_cast<MenuButton*>(m_gameObjects[i]))
            {
                MenuButton* pButton = dynamic_cast<MenuButton*>(m_gameObjects[i]);
                pButton->setCallBack(callBack[pButton->getCallBackID()]);
            }
        }
    }
}

bool MainMenuState::onEnter()
{
    // Parse the state
    StateParser stateParser;

    stateParser.parseState("test.xml", s_menuID, &m_gameObjects, &m_textureIDList);
    m_callBacks.push_back(0);
    m_callBacks.push_back(s_menuToPlay);
    m_callBacks.push_back(s_exitFromMenu);

    //set callbacks for menu items
    setCallBacks(m_callBacks);


    std::cout << "Entering MenuState...";
    return true;

}

bool MainMenuState::onExit()
{
    // clear the texture manager
    for(unsigned int i = 0; i < m_textureIDList.size(); i++)
    {
    theTextureManager::Instance()->clearFromTextureMap(m_textureIDList[i]);
    }


    std::cout << "exiting MenuState.\n";
    return true;
}

void MainMenuState::s_menuToPlay()
{
    theGame::Instance()->getStateMachine()->changeState(new PlayState());
}

void MainMenuState::s_exitFromMenu()
{
    //theGame::Instance()->quit();  NEED TO FIX ALL THESE BITS
    SDL_Quit();
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<States>
    <MENU>
        <TEXTURES>
            <texture filename="images/button.png" ID="playbutton"/>
            <texture filename="images/exit.png" ID="exitbutton"/>
        </TEXTURES>

        <OBJECTS>
            <object type="MenuButton" x="100" y="100" width="400" height="100" textureID="playbutton" numFrames="0" callbackID="1"/>
            <object type="MenuButton" x="100" y="300" width="400" height="100" textureID="exitbutton" numFrames="0" callbackID="2"/>
        </OBJECTS>
    </MENU>

 etc....
etc......

</States>


Too much code to list here
For stack frames #0, #1, #2, the this pointer is null.

This indicates that StateParser::parseTextures (#3) called TiXmlNode::FirstChildElement with an invalid TiXmlNode instance.

Looking at the stack frame for StateParser::parseText, we see that pStateRoot was passed as null. This will cause the for statement at line 75 to fail.
for(TiXmlElement* e = pStateRoot->FirstChildElement();

Going back one more stack frame to StateParser::parseState (#4).
At lline 27, you search for a match on stateId. At line 35, if a match on stateId was not found, pSateRoot will still be null. This causes you to call FirstChildElement on an invalid (null) object.
 
for(TiXmlElement* e = pStateRoot->FirstChildElement();

> TiXmlNode::FirstChildElement(this=0x0)
you are trying to dereference a NULL pointer

In the 'parseState()' function you set 'pTextureRoot' to NULL and pass it like that to 'parseTexture()'
I suppose that line 45 should be pTextureRoot = e;


Also, consider using smart pointers (or no pointers) to avoid memory leaks and bad deletes
yep should have been pTextureRoot = e;

still getting segment faults due to the stateID being null, I need to look more into it but I'm suffering from hay-fever at the moment :"(

Are smart pointers like this:-

pGameObject->load(std::unique_ptr<LoaderParams>(new LoaderParams(x, y, width, height, textureID, numFrames, callBackID, animSpeed)));

I'll need to read up on them if so.
Topic archived. No new replies allowed.