0

私は、それ自体ではレンダリングやウィンドウ管理を行わないが、構造を提供する、小さなエンティティベースのゲームフレームワークを自分で構築しました。実際にはMVCフレームワークに相当します。

現在、SFML 2を使用して単純なウィンドウをレンダリングすることで、これを実践しようとしています。過去にこの環境(Ubuntu 12.04ボックス)でより文字列のコードを使用して実行したことがあるので、SFML2ライブラリが正しく機能していることがわかります。

sf::RenderWindowただし、インスタンスにアクセスしようとすると、セグメンテーション違反が発生します。私はそれをGDBで実行しましたが、すべてがそこにありますが、メソッド(GDBが認識できる)を実行しようとすると、終了します。

これは、このようにウィンドウにアクセスしようとした場合にのみ発生します。

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);
    }
};

ポインタ、、gameはnullではありません。GDBで逆参照すると、のインスタンスが返されますBasicGamegame->windowも存在し、GDBはそれを見るgame->window.createことができます。実行しようとすると、引数を指定しないとうめき声を上げます。

setFramerateLimitブレークポイントを使用してGDBで手動で実行しようとすると、セグメンテーション違反も発生します。

ただし、startメソッドをこれに変更すると...

void start()
{
    sf::RenderWindow window;
    window.create(sf::VideoMode(640, 480), "Basic arc example");
    window.setFramerateLimit(60);
}

それは絶対にうまくいきます。さて、ウィンドウはすぐに閉じますが、セグメンテーション違反はありません。

sf::RenderWindow同じスコープ内にある必要がありますか?デフォルトのコンストラクターはそれを壊しますか?

私はまだC++にかなり慣れていないので、まったく愚かなことをしているかもしれませんが、これについての助けをいただければ幸いです。私は何時間も探していじくり回してきましたが、うまくいきません。うまくいけば、これも十分な情報です。

ありがとう。

編集:

もう少し情報があります。私も同じ結果でclang++試しましたが、コンパイルしています。g++そして、これが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

closeが実行されている理由がわかりません...コードベースで、ウィンドウのcloseイベントをリッスンしているオカレンスが1つあります。取り出しても違いはありません。確認しようと思っただけです。

4

1 に答える 1

1

ポインタgameはnullではありません。GDBで逆参照すると、BasicGameのインスタンスが返されます。

重要な点は、の有効なインスタンスを持つことですBasicGame。提供したコードスニペットから、使用しなかったように見えるnewため、ポインタは割り当てられていないメモリ領域を指しています。

次のコードを検討してください。

int* x = new int;
*x = 58;
delete x;
std::cout << x << " points to the value " << *x << std::endl; // unpredictable behaviour!

削除した後xも古いアドレスを印刷できますが、そのコンテンツにアクセスしようとすると、プログラムがクラッシュする可能性があります(必ずしもそうとは限りません)。

このような間違いを防ぐために、常に属性を追加x = 0;(またはx = nullptr;C ++ 11)して初期化する必要があります:

BasicGameSystem() : game(0) { }

このようにして、プログラムがクラッシュするため、無効なメモリ領域にいつアクセスしたかわかります。

于 2012-10-28T09:25:24.507 に答える