stumpbeard stumpbeard - 27 days ago 9
C++ Question

Crash when attempting to assign child pointer to vector of parent pointers

I've run into a headscratcher, because I'm not getting any errors at compile, just at runtime. Here's some sample code:

entity.h



#ifndef ENTITY_H
#define ENTITY_H

#include <vector>
#include "component.h"

struct Entity
{
std::vector<Component*> components;
};

#endif


Here's my entity. I just want it to hold a list of data components.

component.h



#ifndef COMPONENT_H
#define COMPONENT_H

#include <string>

struct Component
{
std::string name;
};

#endif


Here's the parent of the components. I need it so that entity can have a list of different kinds of children components.

comp_position.h



#ifndef COMP_POSITION_H
#define COMP_POSITION_H

#include "component.h"

struct Position : Component
{
Position(int y, int x) {this->y = y; this->x = x; name = "Position";}

int y, x;
};

#endif


Here's a sample of one of the components. Just contains a 2D location of the entity.

assemblages.h



#ifndef ASSEMBLAGES_H
#define ASSEMBLAGES_H

#include "entity.h"
#include "comp_position.h"

Entity* makePlayer(int y, int x){
Entity* player;
player->components.push_back(new Position(y, x));
return player;
}

#endif


Here's an assemblage so that I can easily build player type entities. The moment of putting a Position pointer into the list of Component pointers is where the program crashes.

main.cc



#include "assemblages.h"
#include "entity.h"

#include <iostream>

using namespace std;

int main()
{
Entity* player = makePlayer(10, 10);

return 0;
}


And finally here's my main where I just try and create a player. As mentioned above, it is during the assemblage that the program is crashing. Any idea what I'm doing wrong? Sorry there are so many files here, I wanted to make sure I was representing my actual program fully while still attempting to strip away as much as I could.

Thank you for any help!

Answer

This line:

Entity* player;

Creates an uninitialized Entity pointer. It doesn't point to a valid object. You need to initialize it, e.g: by allocating an object on the heap using new.

Please note, storing owned objects as bare pointers is not a good practice, it easily leads to memory leaks. Use a unique_ptr instead, which will automatically delete the pointed object when it goes out of scope.