title: Passing pointer to self in constructor c++
body: <p>In a basic game code that I'm developing, I have each separate area of the "map" have a separate Area class that handles combat and a variety of other basic functions. Each entity contained within the Area has a pointer to that Area so it can access Area functions and whatnot, however that pointer is apparently getting deleted or something wonky is happening, because when it tries to dereference it, I get all sorts of run-time errors.</p>
  
  <p>Is it happening because I'm giving each NPC a pointer to the Area in its constructor?</p>
  
  <p>Area Constructor</p>
  
  <pre><code>Area::Area(Game&amp; game, std::string name, std::string id)
  : GameState(game), game(game), player(game.getPlayer()), log(game, "log", 0.0f, 90.0f, 32, game.getFont("Times"), sf::Color::White)
  {
      game.clearStrings();
      this-&gt;id = id;
      this-&gt;name = name;
      game.timer.restart();
      player.setArea(this);
      game.addString(DisplayString(&amp;game, name, name + "title", game.getFont("Celt"), 10.0f, 10.0f, 64, sf::Color::White));
      //
      this-&gt;addEnemy(NPC(game, this, "Skeleton", "skel", 30, 0, 7, 10, 5, 5));
      this-&gt;addEnemy(NPC(game, this, "Skeleton", "skel", 30, 0, 7, 10, 5, 5));
      int offsetY = 0;
      for (std::map&lt;std::string, NPC&gt;::iterator it = enemies.begin(); it != enemies.end(); ++it)
      {
          game.addString(DisplayString(&amp;game, it-&gt;second.getName(), it-&gt;first, game.getFont("Times"), WINDOW_WIDTH, 0, 64, sf::Color::White));
          DisplayString&amp; name = game.getString(it-&gt;second.getID());
          game.addString(DisplayString(&amp;game, std::to_string(it-&gt;second.hp) + " / " + std::to_string(it-&gt;second.maxhp), it-&gt;second.getID() + "hp", game.getFont("Times"), WINDOW_WIDTH, name.Text.getGlobalBounds().height, 64, sf::Color::White));
  
          name.setPos(WINDOW_WIDTH - name.Text.getGlobalBounds().width, offsetY);
          offsetY += name.Text.getGlobalBounds().height;
  
          DisplayString&amp; hp =  game.getString(it-&gt;second.getID() + "hp");
          hp.setPos(WINDOW_WIDTH - hp.Text.getGlobalBounds().width, offsetY+name.Text.getGlobalBounds().height);
          offsetY += hp.Text.getGlobalBounds().height;
      }
  }
  </code></pre>
  
  <p>NPC Constructor</p>
  
  <pre><code>NPC::NPC(Game&amp; game, Area* area, std::string name, std::string id, int hp, int ap, int agil, int str, int dmg, int speed)
  : game(game)
  {
      this-&gt;name = name;
      this-&gt;hp = hp;
      this-&gt;maxhp = hp;
      this-&gt;ap = ap;
      this-&gt;dmg = dmg;
      this-&gt;agil = agil;
      this-&gt;str = str;
      this-&gt;speed = speed;
      this-&gt;area = area;
      this-&gt;id = id + std::to_string(game.enemyID++);
  }
  </code></pre>
  
  <p>This is where I run into troubles dereferencing the area pointer of the NPC class</p>
  
  <pre><code>void NPC::attack(Player&amp; player)
  {
      if (rand() % 100 + 1 &lt; 5)
      {
          int damage = 2 * (this-&gt;dmg + (rand() % 6 - 3));
          player.hp -= damage;
          //any of these area pointers in the debugger show up with garbage data
          area-&gt;log.addLine(this-&gt;name + " critically strikes " + player.getName() + " for " + std::to_string(damage) + "!");
      }
      else
      {
          if (rand() % 100 + 1 &gt; 15)
          {
              int damage = this-&gt;dmg + (rand() % 6 - 3);
              player.hp -= damage;
              area-&gt;log.addLine(this-&gt;name + " hits " + player.getName() + " for " + std::to_string(damage) + "!");
          }
          else
          {
              area-&gt;log.addLine(player.getName() + " dodges!");
          }
      }
  }
  </code></pre>
  
  <p>Keep in mind that there's no shenanigans going on from the Area constructor, to the NPC constructor, to the Attack function. The Area constructor completes, then the game calls the Area's update function, which immediately calls Attack, and nowhere in between is the area pointer being deleted or in any other way modified.</p>
  
  <p>I apologize for the incredibly verbose answer and for kinda dumping a bunch of code at you, but I'm new at all the stuff and really didn't know what to cut out to condense it. If you need any more code to get a better idea of what's going on, I will gladly provide it, I've just banged my head at this for days trying to sort it out with no headway made.</p>
  
  <p>Edit: adding some code that leads to the construction of Area (cut out extraneous code)</p>
  
  <pre><code>void InitState::update()
  {
      if(main.isOpen())
      {
          sf::Event event;
          while (main.pollEvent(event))
          {
              switch (event.type)
              {
              case sf::Event::Closed:
                  main.close();
                  game.Stop();
                  break;
              case sf::Event::KeyReleased:
                  switch (event.key.code)
                  {
                      break;
                  case sf::Keyboard::Key::Return:
                      switch (var)
                      {
                      case NAME:
                          if (writing)
                          {
                              game.delIcon("inputbox");
                              player.setName(game.getString("input").Text.getString());
                              game.addArea(Area(game, "The Cave", "cave"));
                              game.setState(&amp;game.getArea("cave"));
                          }
                      default:
                          break;
                      }
                      break;
                  }
                  break;
          }
      }
  }
  </code></pre>
  
  <p>InitState is a GameState, which Area is as well. When the game loops, it calls state->update() and render(), so when the game sets a state, it switches over to that class's update and render functions.</p>
  
  <p>Area's update function</p>
  
  <pre><code>void Area::update()
  {
      if (game.getWindow().isOpen())
      {
          sf::Event event;
          while (game.getWindow().pollEvent(event))
          {
              if (event.type == sf::Event::Closed)
              {
                  game.getWindow().close();
                  game.Stop();
              }
              if (event.type == sf::Event::KeyReleased)
              {
                  if (event.key.code == sf::Keyboard::Key::Return)
                  {
                      doCombat(); // calls attack functions for NPC and player
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>EDIT EDIT: More code!
  areas is an std::map</p>
  
  <pre><code>void Game::addArea(Area area)
  {
      areas.emplace(area.getID(), area);
  }
  
  Area&amp; Game::getArea(std::string id)
  {
      return areas.find(id)-&gt;second;
  }
  </code></pre>