Question

I have a method who put some content on my vector, that work with no problem. After that I want to reuse the content on my vector in another part of the program, but the problem is the values are not he good. But I don't know where I miss something

Here is some part of the code

The class where I do the stuff

class MapGenerator
{

public:
    void fillBoard(string level);
    void renderBoard();
    void initTileset();
    MapGenerator();
    ~MapGenerator();
    vector<Tile*> getTiles();

private:
    char     **board;
    int w;
    int h;
    int tileW;
    int tileH;
    vector<Tile*> tiles;

};

It's on the initTileset I put some stuff on my tiles vector.

After that on another part of my programe I call renderBoard() And there is the problem, I already have the good number of element on my vector but the values are not the good...

Here is the method, maybe my way to itterate is not correct :

Where I put the content on vector

void MapGenerator::initTileset()
{
    XMLDocument doc;
    doc.LoadFile("ressources/xml/tiles.xml");
    XMLElement* first = doc.FirstChildElement();

    for (XMLElement* child = first->FirstChildElement("tile"); child != NULL; child = child->NextSiblingElement())
    {
      string texture = child->FirstChildElement( "texture")->GetText();
      int x =  atoi(child->FirstChildElement("x")->GetText());
      int y =  atoi(child->FirstChildElement("y")->GetText());
      int w =  atoi(child->FirstChildElement("w")->GetText());
      int h =  atoi(child->FirstChildElement("h")->GetText());
      bool solid = false;
      if (atoi(child->FirstChildElement("solid")->GetText() ) == 1)
        solid =true; 
      char id = child->FirstChildElement("id")->GetText()[0];
      cout << "ID " << id << endl; 
      cout << "create tile : w " << w << " h " << h << endl;
      Tile tile(texture.c_str(), x, y, w, h, solid, id);
      cout << "Tile ID " << tile.getId()<< endl; 

      this->tiles.push_back(&tile);
    }
      cout << tiles.size() << endl;
     // renderBoard();
}

Where I try to reuse my vector

void MapGenerator::renderBoard()
{   
    SDL_Rect rect;
    for (int i = 0; i < h; i++)
    {
        for (int j = 0;j < w; j++)
        {
            vector<Tile *>::iterator it;
            for(it = tiles.begin(); it != tiles.end(); ++it) {
                cout <<  " ID :"  << (*it)->getId()  << " h " <<(*it)->getRect().h << " w " << (*it)->getRect().w << endl; 
                if ((*it)->getId() == board[i][j])
                {
                    rect.x = 32 * j;
                    rect.y = 32 * i;
                    rect.h = 32;
                    rect.w = 32;
                    SDL_RenderCopy( GameEngine::getInstance().getRenderer(), (*it)->getTexture(), NULL, &rect );
                     cout << " copy something y = " << i * 32<< " x = " << j *32<< " h " <<(*it)->getRect().h << " w " << (*it)->getRect().w <<endl;
                }
             }
        }
        cout << endl;
    }
}

So someone have an idea ?

Was it helpful?

Solution

You have undefined behavior as you store pointers to a local variable in the vector. Once the for loop in the initTileset function iterates the tile variable goes out of scope and is destructed.

You need to allocate it on the heap:

Tile* tile = new Tile(texture.c_str(), x, y, w, h, solid, id);

You should of course not forget to free the allocated memory in the MapGenerator destructor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top