0
votes

I'm having problems creating a tmx map from string input.

bool LevelManager::initLevel(int currentLevel)
{
    const char* map;
    try {

        map = LevelManager::getLevel(currentLevel);
    } catch (int) {
        throw 1;
    }
    if(map != NULL){
        CCLog("%s", map);
        tileMap = CCTMXTiledMap::create(map);
        tileMap->setAnchorPoint(ccp(0,0));
        tileMap->setPosition(ccp(15,20));
        this->addChild(tileMap, 5);
        backgoundLayer = tileMap->layerNamed("Background");
    } else {
        throw 1;
    }
    return true;
}

Thats my code. It is very unstable. Most of the times it crashes and sometimes it doesn't. I'm loading my map from the string map. Wich is a const *char. My map is named Level1.tmx and when i load the map like this: tileMap = CCTMXTiledMap::create("Level1.tmx"); it always works and never crashes. And i know for a fact that the value of map is Level1.tmx because i log it in the line before the load.

When it crashes the log outputs this: (lldb) and on the line tileMap->setAnchorPoint(ccp(0,0)); it says "Thread 1: EXC_BAD_ACCESS (code=2, adress=0x0)

Does anyone know why this happens and how to fix it?

Many thanks.

Ps: i'm using xcode, the latest cocos2d-x release and the iPhone simulator

Edit:

Using breakpoints i checked where things go bad while loading the tilemap.

on the line tileMap = CCTMXTiledMap::create(map); my variable map is still fine

but on line tileMap->setAnchorPoint(ccp(0,0)); it is suddenly corrupted (most of the time)

2

2 Answers

1
votes

It sounds like you're returning a char* string created on the stack, which means the memory may or may not be corrupted, depending on circumstances, moon phases, and what not.

So the question is: How is getLevel defined and what does it do (post the code)?

If you do something like this:

const char* LevelManager::getLevel(int level)
{
    char* levelName = "default.tmx";
    return levelName;
}

…then that's going to be the culprit. The levelName variable is created on the stack, no memory (on the heap) is allocated for it. The levelName variable and the memory it points to become invalid as soon as the method returns.

Hence when the method leaves this area of memory where levelName points to can be allocated by other parts of the program or other method's stack memory. Whatever is in that area of memory may still be the string, or it may be (partially) overridden by other bits and bytes.

PS: Your exception handling code is …. well it shows a lack of understanding what exception handling does, how to use it and especially when. I hope these are just remnants of trying to get to the bottom of the issue, otherwise get rid of it. I recommend reading a tutorial and introductions on C++ exception handling if you want to continue to use exceptions. Especially something like (map != NULL) should be an assertion, not an exception.

0
votes

I fixed it.

const char* was to blame.

When returning my map as a char * it worked flawless.

    const char *levelFileName = level.attribute("file").value();
    char *levelChar = new char[strlen(levelFileName) + 1];
    std:: strcpy (levelChar, levelFileName);

return levelChar;

Thats how i now return the map.