jkazan
jkazan

Reputation: 1199

Why does pointing to a vector element's member lead to segmentation fault?

I have a class Game and a struct NamedGame. NamedGame has two member variables as seen below:

  struct NamedGame {
    Game game;
    std::string name;
  };

I then have a vector with NamedGames:

std::vector<NamedGame> games;

A pointer shall point to the currently active game:

  Game *currentGame;

Now, when I try to point at the last NamedGame in the vector games as follows:

  *currentGame = games.back().game;

It leads to a segmentation fault. What am I doing wrong, and why is it wrong? I truly appreciate all help!

#include <vector>
#include <string>

struct Game {};
struct NamedGame {
  Game game;
  std::string name;
};

int main() {
  std::vector<NamedGame> games;
  Game *currentGame;
  *currentGame = games.back().game;
}

Upvotes: 2

Views: 88

Answers (2)

Trevor
Trevor

Reputation: 366

In my experience, seg faults are almost always due to dereferencing a null pointer. The culprit, as pointed out by Mahmoud, is most likely due to the following line:

*currentGame = games.back().game;

Where currentGame may not have been initialized yet. Storing the reference of games.back().game works, but you should also ask "Why am I using pointers in the first place?" If you are trying boost performance or reduce space used by working with pointers, why not do the following:

#include <vector>
#include <string>

struct Game {};
struct NamedGame 
{
  Game *game;
  std::string name;
};

int main() 
{
  std::vector<NamedGame> games;
  Game *currentGame

  //Code to initialize NamedGames and push them onto games

  if (NULL != games.back().game)
  {
    currentGame = games.back().game;
  }
}

This way, you are still working with pointers, but you are also making it so that the developer SHOULD verify that Game is not NULL before dereferencing it.

However, if you are using pointers just "for fun", I'd recommend making currentGame as type Game rather than Game * to avoid using pointers all together. If you go that route, I'd also recommend overloading the assignment operator of Game, depending on what you are doing with the currentGame variable.

Upvotes: 0

Mahmoud Fayez
Mahmoud Fayez

Reputation: 3459

Here you are trying to deference the pointer currentGame while it is not initialized:

*currentGame = games.back().game;

You have to change this line to be:

currentGame = &(games.back().game);

Upvotes: 4

Related Questions