Reputation: 41352
I have built myself a little entity based game framework that does no rendering or window management by itself but provides structure. An equivalent to an MVC framework really.
I am now trying to put it into practice by rendering a simple window with SFML 2. I have done it in the past in this environment (my Ubuntu 12.04 box) with more stringy code, so I know my SFML 2 libraries are working correctly.
I am however getting a segmentation fault when trying to access my sf::RenderWindow
instance. I have run it through GDB and everything is there, but when trying to execute a method (which GDB can see), it dies.
This only happens though if I try to access my window like this.
class BasicGame : public arc::Game
{
public:
sf::RenderWindow window;
};
class BasicGameSystem : public arc::System
{
protected:
BasicGame* game;
};
class RenderSystem : public BasicGameSystem
{
public:
void start()
{
game->window.create(sf::VideoMode(640, 480), "Basic arc example");
game->window.setFramerateLimit(60);
}
};
The pointer, game
, is not null. I can dereference it in GDB and it will return an instance of BasicGame
. game->window
also exists, and GDB can see game->window.create
, it will even moan at me for not supplying any arguments if I try to execute it.
If I try to execute setFramerateLimit
manually with GDB using a breakpoint it will also segfault.
If I change my start method to this though...
void start()
{
sf::RenderWindow window;
window.create(sf::VideoMode(640, 480), "Basic arc example");
window.setFramerateLimit(60);
}
It works absolutely fine. Well, the window closes instantly, but no segfault.
Does sf::RenderWindow
need to be in the same scope? Does it's default constructor break it?
I am still pretty new to C++, so I may be doing something utterly stupid, but any help on this would be much appreciated. I have been searching and tinkering for hours but I just can't work it out. Hopefully this is enough information too.
Thanks.
Edit:
Just for a little more information. I am compiling with clang++
although I have tried g++
too with the same result. And here is the backtrace from GDB.
#0 0xb7cd0981 in sf::Window::close() () from /usr/local/lib/libsfml-window.so.2
#1 0xb7cd131e in sf::Window::create(sf::VideoMode, std::string const&, unsigned int, sf::ContextSettings const&) ()
from /usr/local/lib/libsfml-window.so.2
#2 0x080496a3 in RenderSystem::start (this=0xbffff0f0) at examples/basic.cpp:26
#3 0x0804b60e in arc::SystemList::add (this=0xbffff128, system=0xbffff0f0) at src/SystemList.cpp:17
#4 0x08049f79 in arc::Game::addSystem (this=0xbffff128, system=0xbffff0f0) at src/Game.cpp:11
#5 0x08048cfc in main () at examples/basic.cpp:73
I have no idea why close is being run... I have one occurrence in my codebase which is listening for the window close event. Taking it out makes no difference. Just thought I would make sure.
Upvotes: 0
Views: 980
Reputation: 3530
The pointer, game, is not null. I can dereference it in GDB and it will return an instance of BasicGame.
The key point is to have a valid instance of BasicGame
. From the code snippet you gave, it looks like you didn't use new
so your pointer is pointing to a non-allocated memory region.
Consider the following code :
int* x = new int;
*x = 58;
delete x;
std::cout << x << " points to the value " << *x << std::endl; // unpredictable behaviour!
After deleting x
you still can print its old address but if you try to access its content you might (but not necessarily) crash your program.
To prevent such mistake your should always add x = 0;
(or x = nullptr;
in C++11) and initialise your attributs :
BasicGameSystem() : game(0) { }
This way, you will know when you access invalid memory region because your program will crash.
Upvotes: 1