Segfault when using std::set of pointers... can anyone explain this? - c++

In my game I created a base class called Entity which I store in a set for processing. All my game objects derive from this class, and I have no problem adding the derived pointer types to the set in my initialization function.
The problem lies in adding new elements from within an Entity's Step() function. Now, before I get too far into it I'll show you some simplified code:
class GameState
{
public:
GameState();
~GameState();
...
set<Entity*> entities;
void Add(Entity* e);
void Remove(Entity* e);
protected:
set<Entity*> added, removed;
};
class Entity
{
public:
Entity();
Entity(GameState* parent);
virtual ~Entity();
virtual void Step(const sf::Input& input);
...
virtual void Destroy();
protected:
GameState* game;
};
The functions Add and Remove in GameState simply add the argument e to the added and removed sets respectively. In the main loop (elsewhere in GameState), I move the elements from added to entities before processing and after processing I remove elements from removed from entities. This ensures that entities is not modified during iteration.
The Add/Remove functions are very simple:
void GameState::Add(Entity* e)
{
added.insert(e);
}
void GameState::Remove(Entity* e)
{
removed.insert(e);
}
Every derived Entity is passed a pointer to GameState in it's constructor that it keeps as game. So theoretically from the Step function I should be able to Add and Remove entities with a simple call like game->Remove(this);, but instead I get a segfault. After a night of googling and coming up with nothing, I was able to work around (part of) the problem by implementing Entity::Destroy() like so:
void Entity::Destroy()
{
game->Remove(this);
}
So my first question is: Why does this work when I'm in the base class but not in the derived class?
Even more puzzling to me is Add(). Why does Add(new Explosion(16,16,this)) work in GameState but game->Add(new Explosion(16,16,game)) doesn't work inside my object?
I ran it through gdb and it tells me:
Program received signal SIGSEGV, Segmentation fault.
At c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:482
The code that throws the error is:
_Link_type
_M_begin()
{ return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } //this line
So to sum it up I have no idea why my pointers break the STL... and I get that grave feeling that I'm missing something very basic and its causing all these headaches. Can anyone give me advice?

Why does Add(new Explosion(16,16,this)) work in GameState but
game->Add(new Explosion(16,16,game)) doesn't work inside my object?
If that is the case then the only possible explanation is that the Entity's game member doesn't actually point to the GameState. Check that it is being set properly on construction and verify before you use it.
This has nothing to do with std::set. The problem is that you are using an std::set that is part of a class that you are accessing via a corrupt pointer.

Related

C++ nonstatic member reference must be relative to a specific object

First things first, I think it will make more sense to see my code. Header:
#include <vector>
#include "GUIItem.h"
class WindowManager
{
private:
static WindowManager* s_wndmgr; //A singleton maintains a pointer to itself as a class variable
std::vector<GUIItem*> m_guilist; //storage for gui item
//...
public:
static void Create();
static void Destroy();
static inline WindowManager* Get()
{
return s_wndmgr;
}
static void addItem(GUIItem *newGUIItem);
};
And the class:
#include "WindowManager.h"
#include "GUIButton.h"
WindowManager* WindowManager::s_wndmgr = NULL;
WindowManager::WindowManager()
{
s_wndmgr = NULL;
}
WindowManager::~WindowManager()
{
//Cleanup other stuff if necessary
delete s_wndmgr;
}
void WindowManager::Create()
{
if ( !s_wndmgr ) s_wndmgr = new WindowManager();
GUIButton *m_btn1 = new GUIButton();
addItem(m_btn1);
}
void WindowManager::Destroy()
{
if ( s_wndmgr ) delete s_wndmgr;
}
void WindowManager::addItem(GUIItem * newGUIItem)
{
m_guilist.push_back(newGUIItem);
}
Hopefully it makes some kind of sense. I'm trying to create a simple gui framework from scratch in OpenGL and this is a simple window manager. My issue is with m_guilist which should be accessible so that new GUIItems can be added to it such as happens in Create (GUIItem being a base class from which others inherit, such as GUIButton).
In this case I'm using addItem in order to append items to the list but I'm running into the a nonstatic member reference must be relative to a specific object error regarding the line inside addItem. I'm a little confused as to why this is the case. I understand that making addItem static is the reason for this error, but that was done in order for it to be called from within Create. Is there a way around this?
Sorry, this is quite the poor question and my grasp of C++ isn't great yet though I'm getting there. Any thoughts on this? Something tells me I'd be better to leave the Create function alone and create another nonstatic function to create my GUIItems and add them to the list.
addItem is a static function, which does not not operate on any instance of WindowManager. It can not access m_guilist, which is non-static without an instance.
Maybe you just want:
Get()->m_guilist.push_back(newGUIItem);
But you're starting to make the interface static, that's kind of hybrid. It's usually that addItem is non-static and you call it with the instance you acquire by WindowManager::Get().
Yet, WindowManager doesn't have inaccessible or deleted constructor to qualify as a singleton class. Ways to implement a Singleton design pattern.

Cocos2d-x PhysicsContact Object Reference

I'm trying to make a videogame with C++ in Cocos2d-x but I have an issue with PhysicContact.
In my gamescene I have a contact listener that check for collisions with the character and objects' PhysicBody of class Item. It all works fine, but now I want to recognize what object has collided because I want to call a method of the object's class called getThrow().
class Item : public cocos2d::Layer
{
public:
Sprite* itemArt;
int itemType;
PhysicsBody* itemCollider;
void createArt(int type);
void getThrow();
Item(int type);
};
I have tried it with the PhysicContact information, first I obtain the object PhysicBody and then its Node, but with this I just obtain the object's Sprite and at this point I don't know how to reach the object to call his method.
bool Level0::onContactBegin(PhysicsContact &contact)
{
auto bodyA = contact.getShapeA()->getBody()->getNode();
auto bodyB = contact.getShapeB()->getBody()->getNode();
//HERE IS WHERE I WANT TO RUN bodyB->getThrow()
return true;
}
I also have tried with getUserData() and getUserObject() but I don't know how to call a method with an object pointer.
I don't know if I'm trying something incorrectly, but I would appreciate your answers.
Thanks in advance! (If more details are needed just tell me, I'm new at this big community)
You need to do this:
((Item*) b->getNode())->getThrow();

Calling subclass methods from superclass object, virtual functions

I'm designing a chess game (C++ beginner) however I'm stuck on my checking process for individual piece types, eg pawn moving only 1 space at a time, except the first time moving 2 spaces, and so on.
I have a piece class, and a subclass of that is pawn, king, etc, which contains the method:
check(string position,string destination);
and return a boolean value whether it is possible to move to the destination.
I have a pointer to each piece which I have defined by doing:
pawn pawnPieces[16];
piece *pointer[16];
for (i=0;i<16;i++)
{
pointer[i]=&pawnPieces[i];
}
After my initial checking, I want to call the check function above from main, as a test:
cout << pointer[1]->check("B1","C1") << endl;
This gives me the error "no member named 'check' in piece" which makes sense, however I'm sure there would be a way to link the piece class to the pawn, king etc.
I think I need to do something with virtual functions from what I have read, but I am not sure how to approach this. If anyone could offer a few pointers that would be much appreciated.
This approach of trying to call the subclass function from a pointer to the class above it may be fundamentally flawed, perhaps I need to modify my design to achieve this goal? I still want to keep the check method of the pawn class in the same position, as I believe it encapsulates it well.
EDIT: I made a pure virtual function in the piece class:
virtual bool check(string positionIN,string destination)=0;
Now when I call the cout line above, I get a segmentation fault and I'm unsure why. I'm assuming it's because I'm using pointers?
EDIT2: Thank you for that! I have implemented this however I got a small error, is virtual meant to be attached to the pawn and king class? From my understanding I thought the virtual tag only goes on the base class.
EDIT3: I understand, I tagged the check function in classes pawn and king with the virtual tag and it compiled.
Now I am getting a segmentation fault through calling the object itself
pawnPieces[1].check("B1","C1")
and by calling the pointer to the object
pointer[1]->check("B1","C1")
from main, and I am not sure why.
EDIT4: All working now, I was calling it from main to test, however when I called it from within my program everything worked, thank you all!
What you are attempting to do is exactly what virtual methods are meant for.
class piece
{
public:
virtual bool check(string position, string destination) = 0;
};
class pawn : public piece
{
public:
virtual bool check(string position, string destination)
{
return ...;
}
};
class king : public piece
{
public:
virtual bool check(string position, string destination)
{
return ...;
}
};

Pass class instance C++

I'm learning C++ by programming a game. I'm using SDL to display my objects and a factory structure to keep it all organised.
I separated the first object (a car), the controls (keyboard) and the display (monitor).
In my main class I call the monitor class to display a window where I should draw the images. If a key is pressed, the car should react to that by redrawing the image.
The problem here is that I initialized the monitor in the main class and I can't access it in my car class..
I tried a variety of things, but nothing seems to do the trick.
So here is the main class
Game::Game(GuiFactory* factory) {
bool is_running = true;
Car* car = factory->createCar();
car->drawCar();
// create factory specific window
Monitor* monitor = factory->createMonitor();
// create factory specific keyboard
Keyboard* keyboard = factory->createKeyboard();
while (is_running) {
// keyboard input
string key_input = keyboard->getKeys();
if (key_input == "quit") {
is_running = false;
} else if (key_input != "") {
if(key_input == "right"){
car->turnRight(monitor);
}
}
}
}
I have a main car class and an SDLCar class, which inherits car.
class Car {
public:
Car();
virtual ~Car();
virtual void drawCar() = 0;
virtual void turnRight() = 0;
};
Here is where I'm confused:
class SDLCar : public Car {
public:
SDLCar();
virtual ~SDLCar();
void drawCar();
void turnRight(SDLMonitor& monitor);
// ^^^^^^^^^^^^^^^^^^^
};
Could someone please explain?
In your base class Car you have declared the method turnRight which takes no parameters.
In your derived class SDLCar you have declared a completely different method with the same name. The reason why it's a different method and not a function override is that its takes a parameter. It should be parameterless to override Car::turnRight.
And because it's not a function override, the rules of polymorphism don't apply. Thus you can't call SDLCar::turnRight(SDLMonitor&) from a Car pointer.
Right now is an excellent time to start using the override keyword. It prevents specifically these kind of programming errors. By marking a function with override:
void turnRight(SDLMonitor& monitor) override;
the compiler will automatically check that it actually overrides a function from the base class.
E.g. with the above declaration, the compiler would give you an error (or a warning at least). This would've helped you find your error right away and prevented more erroneous code such as car->turnRight(monitor).
So now that the error is found, you need to find a way to fix it. Either declare the base class turnRight to take a SDLMonitor& as well, or think of something else if that's not how it should behave.
IMO having to pass the game window to a method like turnRight seems weird. Why would turning a car need a window? I think turnRight should do just what it says on the tin: turn the car right. Nothing else.
I don't know why you're passing a window to the method but if it's for drawing, shouldn't the drawCar method handle that? I don't know your code, so I'll leave it up to you.

Converting objects of base class to derived class

I asked a couple days ago some clarifications on inheritance, a concept I am still trying to understand. Here is the follow up question, since I am still facing problems.
In my project I have 2 types of objects, Hand and Face, both inheriting from the base class BodyPart. BodyPart is something like this:
class BodyPart
{
public:
typedef boost::shared_ptr<BodyPart> BodyPartPtr;
BodyPart();
virtual ~BodyPart();
private:
int commonMember1;
double commonMember2;
public:
int commonMethod1();
int CommonMethod2();
}
while Hand is something like this:
class Hand : public BodyPart
{
public:
Hand();
~Hand();
private:
int numFingers;
double otherVar;
public:
int getNumFingers();
void printInfo();
}
I also have a vector of BodyPart elements
std::vector<BodyPart::BodyPartPtr> cBodyParts;
composed of Hand or Head objects. In the previous question I was told that this approach makes sense, I just had to cast from the base class to the derived using boost static_pointer_cast
Now, the problem now is that for some of the objects in the vector I don't know whether they are Hand or Head, so at some point in my code I can have in cBodyParts some Hand elements, some Head elements as well as some BodyPart elements. After some further analysis I am able to correctly classify the latter as either Hand or Head and modify accordingly the elements in the vector, but I have no idea on how to make it. Shall I just delete the case class element and create a derived one with the same property? Shall I just avoid inheritance in case like this?
Thanks in advance for the help
EDIT: I have augmented the examples to make them clearer.
Relaying on casts is usually a sign of a bad design. Casts have their place, but this does not look to be it.
You need to ask yourself what do you want to do with the objects stored in cBodyParts. For sure, you will be doing different things with a Hand or with a Head, but you can probably abstract them somehow: this is what virtual functions do. So, in addition to what you have already written for your classes, you would just need an additional virtual function in them:
class BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}
class Head : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Head
}
// Since a Head has no joints, we don't override the CalibrateJoints() method
}
class Hand : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Hand
}
virtual void CalibrateJoints() {
// Code to calibrate the knuckles in the hand
}
}
And then you no longer need any casts. For instance:
for (BodyPart::BodyPartPtr part : cBodyParts) {
part->InitialisePart();
part->CalibrateJoints(); // This will do nothing for Heads
}
As you can see, no casts at all and everything will work fine. This scheme is extensible; if you later decide that you need additional classes inheriting from BodyPart, just write them and your old code will work correctly:
class Torso : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Torso
}
// The Torso has no joints, so no override here for CalibrateJoints()
// Add everything else the class needs
}
class Leg : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Leg
}
virtual void CalibrateJoints() {
// Code to calibrate the knee
}
// Add everything else the class needs
}
Now you don't need to change the code you wrote previously: the for loop above will work correctly with and Torso or Leg it finds with no need for an update.
The hip bone's connected to the thigh bone...
I take it you have some composite of all the body parts, maybe a Body class.
What do you want the body to do?
Render itself
Serialise
Ouput its volume, or bounding box, or some other metric
Re-orient itself in response to input
Respond to an inverse-kinematic physical model
The list could probably go on. If you know exactly what you want the Body to do you can put that function in the BodyPart base class, and have Body iterate over the composite hierarchical structure of all the connected body parts, calling render, for example.
An alternative is to use a Visitor, which is effectively a way of dynamically adding methods to a static inheritance hierarchy.
As Kerrek SB pointed out this is not feasible at all, but for the sake of answering the actual question, dynamic_cast is what you are looking for.
Use virtual functions, they will simplify a lot your problem.
Else, you can add some methods to distinguish between different types. However, do it only if you cannot do it another way, ie if you cannot do it via virtual functions.
Example 1:
// in BodyPart; to be reimplemented in derived classes
virtual bool isHand() const { return false; }
virtual bool isHead() const { return false; }
// in Hand (similar to what will be in Head)
bool isHand() const { return true; }
// How to use:
BodyPart::pointer ptr = humanBodyVector[42]; // one item from the array
if(ptr->isHand())
processHand(/*cast to hand*/)
else if(ptr->isHead())
// ...
Example 2: let the derived classes handle the cast
// in BodyPart; to be reimplemented in derived classes
virtual Hand* toHand() const { return 0; }
virtual Head* toHead() const { return 0; }
// in Hand (similar to what will be in Head)
Hand* toHand() const { return this; }