2017-05-28 4 views
0

これはC++メモリ管理上の問題ですので、私はここで質問しました。 私はSFMLでゲームを作成しています。以前はSDLを使用していましたが、テクスチャを管理するのは非常に簡単でしたが、SFMLの動作は異なります。SFMLテクスチャメモリ管理

マイプロジェクトのセットアップはとてもようなものです:

class Game 
//create window and initialize game stuff 

class Character 
/*initializes its own textures and is also responsible for updating itself 
as well as drawing itself*/ 

int main() 
/*create an instance of Game -> Create an instance of Character and 
runGame. I will implement the drawing and updating properly when I 
implement a scene graph and scene nodes but for now updating and drawing is 
done via global functions called by the Game Class*/ 

私が直面した課題は白い長方形でスプライト画像結果の文字クラスにSF ::テクスチャを使用して描かれているということでした。文字スプライトはテクスチャリンクを失い、SFMLは白い四角形を描画します。これを解決するために、生のテクスチャポインタを作成し、それをCharacterコンストラクタで初期化しました。これが動作し、Spriteが正しく描画されます。

//inside character.hpp 
sf::Texture *texture; 

//in Character constructor 
texture= new (sf::Texture); 

これはメモリを管理しなければならず、コードが醜いと感じることを意味します。

私は、メモリリークを防ぐために割り当てられたメモリ(と思う)を管理するために、これを試してみました:

Character::~Character() 
{ delete texturePtr; } 

が、それは明らかに間違っています。 私はまた、アプリケーションを終了するが、エラーの原因となるmain()の終わりにcharacter.Textureを削除しようとしました。

私は、文字コンストラクタ内uinque_ptrを使用する実行しようとしました:

std::unique_ptr<sf::Texture> texture(new sf::Texture); 
//load Texture from Resource Manager instance 

、これは代わりに、スプライトテクスチャの素敵なネイビーブルー、黒の四角形を描画します。どうやって宣言して後でunique_ptrを初期化できるかわからない。

私はメモリが漏れていると思います。どうすれば正しくスマートポインタを使用したり、自分のメモリを適切に管理できますか?

私は漠然としていると分かりましたが、少し詳細とコードを追加しました。また、私はテクスチャを照会してSprite Rectディメンションを設定して確実にロードされるようにしていますが、安全のために、呼び出し元のリソースがロードされているかどうかを確認するログ機能があります。

+0

あなたが間違っていることを確認するのに十分なコードを教えてくれませんでした。つまり、 'unique_ptr'を使うのは良い考えです。あなたのテクスチャが青くなっている場合は、初期化バグのように聞こえます。また、 'unique_ptr <...> foo(new whatever)'の代わりに 'make_unique'を使うことを検討してください。 – Rook

+0

あなたはあなたの古いやり方には問題があったと言いましたが、決してそれについて質問しませんでした。あなたは、あなたが持っていてはならない問題に対する解決策を探しています。あなたは*白いスプライトの最初の問題*についての質問をするべきです。 – nvoigt

答えて

2

sf::TextureCharacterのメンバーである場合、あなたのCharacterインスタンスが行うまで、それははスコープの外に行くことはありません。

デバッガブレークポイントを使用して、何が起こるかを追跡します。 Charactersf::Textureのデストラクタにブレークポイントを投げ、スタートアップとシャットダウンシーケンスを実行します。または、ログを使用して "Character ::〜called"のようなメッセージを表示します。


私はメモリをリークしていますし、もしそうなら、どのように私は正しくスマートポインタを使用するか、または適切に私自身のメモリを管理すると思いますか?

質問テクスチャを正しく読み込んでいることを含め、すべての前提条件を確認してください。テクスチャの描画が画面に表示されるまでは、テクスチャをロードしたという証拠はありません。 (の紺色の矩形でなければ何を描こうとしているのか分かりません。)SFMLドキュメントから

LOADFROMFILE機能は時々明らかな理由で失敗することができます。まず、SFMLが標準出力に出力するエラーメッセージを確認します(コンソールを確認してください)。メッセージがファイルを開くことができない場合、作業ディレクトリ(ファイルパスが相対的に解釈されるディレクトリ)があなたの考えであることを確認します。デスクトップ環境からアプリケーションを実行すると、作業ディレクトリ実行可能フォルダです。ただし、IDE(Visual Studio、Code :: Blocks、...)からプログラムを起動すると、代わりに作業ディレクトリがプロジェクトディレクトリに設定されることがあります。これは、通常、プロジェクト設定でかなり簡単に変更できます。

リークディテクタでリークが確認されるまで、実際にメモリがリークしていると想定することはできません。あなたのプログラムに追加できるサードパーティのメモリトラッカーがあります。

また、sf::Textureデストラクタでデバッグブレークポイントを使用して実行を停止し、割り当てを解除する場所(問題が発生している場合)を正確に確認します。


あなたは本当にMinimal, Complete, and Verifiable exampleを読んで従うべきです。私たちが知っている限り、あなたは次のようなことをすることができます。

class Character{ 
    sf::Sprite mySprite; 

    public: 
    Character(){ 
     sf::texture aTex; 
     aTex.loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png"); 

     mySprite.setTexture(aTex); 
    } 
} 

// attempt 2 
class Character{ 
    sf::Sprite mySprite; 

    public: 
    Character(){ 
     std::unique_ptr<sf::Texture> texture(new sf::Texture); 
     texture->loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png"); 

     mySprite.setTexture(*texture); 
    } 
} 

エラーが明らかです。

+0

私はVisual Studio 2013でMSVC++を使用していますが、私は追跡漏れを読んでいますが、私はコーディング中に入る前に確かめたいと思っていました。私は少し詳細を追加する私の質問を編集しましたが、あなたの答えから、私はメモリリークのバグがあるまで、私はRawポインタを削除する心配を停止する必要が示唆されているようです。 – zimspy