2016-12-22 15 views
-2

私はLazyFooの素晴らしいチュートリアル(http://lazyfoo.net/tutorials/SDL/10_color_keying/index.php)に基づいて単純なカラーキーイングエンジンの例を実装しようとしていますが、実行しようとするとスレッドはEXC_BAD_ACCESS 1、address = 0x0)がポインタにヌルかどうかをテストしようとしているにもかかわらず、NULLをチェックしようとしたときにEXC_BAD_ACCESS

//Texture wrapper class 
class LTexture 
{ 
public: 
    //Initializes variables 
    LTexture(); 
    //Deallocates memory 
    ~LTexture(); 
    //Loads image at specified path 
    bool loadFromFile(std::string path); 
    //Deallocates texture 
    void free(); 
    //Renders a texture at a given point 
    void render(int x, int y); 
    //Gets an image's dimensions 
    int getWidth(); 
    int getHeight(); 
private: 
    //The actual hardware texture 
    SDL_Texture* mTexture = NULL; 
    //Image dimensions 
    int mWidth; 
    int mHeight; 
}; 

、ここでintializeだとメソッドを破壊する:ここでは、クラスは次のようになります

LTexture::LTexture() 
{ 
    //Initialize 
    mTexture = NULL; 
    mWidth = 0; 
    mHeight = 0; 
    printf("I initialized"); 
} 

LTexture::~LTexture() 
{ 
    free(); 
} 

そして、私のエラーがLTexture::free方法にあります。

void LTexture::free() 
{ 
    //Free texture if it exists 
    if (mTexture != NULL) //HERE IS THE ISSUE. WHAT IS WRONG WITH THIS? 
    { 
     SDL_DestroyTexture(mTexture); 
     mTexture = NULL; 
     mWidth = 0; 
     mHeight = 0; 
    } 
} 

あなたはインラインで見ることができるように、mTextureがNULLであれば、私がテストしたときの問題は、私が有効であるべきだと考えており、表示されますが、何らかの理由でそうではありません。私は間違って何をしていますか?コードの詳細を投稿するのに役立つでしょうか?

+0

はい、そうです。あなたはおそらくテクスチャをコピーしていますが、あなたのコードはこれを適切に処理しません。 – user3684240

+0

私は理解していません...どこでテクスチャをコピーしていますか?私はfree()がテクスチャがコピーされているかどうか気にしないと思った? – WulffHunter

+1

それは彼が意味するものではありません。 1. 'LTexture(const LTexture&)= delete;'をクラス定義に入れます。 2.コンパイルすると、オブジェクトクラスのインスタンスをコピーしている場所がすぐに表示されます(これはもはや実行できないためです)。詳細については、[3つのルール](https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming))を参照してください。 – WhozCraig

答えて

0

おそらく、正しくコピーして移動することができないという問題があります。

LTextureをコピーするたびに、ポインタだけがコピーされます。コピーが範囲外になると、デストラクタが呼び出されます。次に、ある点で元のスコープが範囲外になり、デストラクターが同じポインター上で再度呼び出され、二重解放が行われます。

私は、スマートポインタを使用することをお勧めします:

#include <memory> 
class TextureDeleter { void operator()(SDL_Texture* t) { SDL_DestroyTexture(t); }; 

// in the class 
std::unique_ptr<SDL_Texture, TextureDeleter> mTexture; 

あなたは、あなたのデストラクタを削除することができます。

編集:あなた本当に<memory>を使用しない場合、その後、あなたは自分のクラスに

LTexture(const LTexture &) = delete; 
LTexture& operator=(const LTexture &) = delete; 
LTexture(LTexture &&) = delete; 
LTexture& operator=(LTexture &&) = delete; 

を追加することにより、安全性の同じ種類を達成することができます。

しかし、コメントに指摘されているように、これは実際にクラスを移動またはコピーする必要がない場合にのみ機能します。あなたがそうするなら、あなた自身を作ることは自明ではないshared_ptrを使用しなければなりません。

+0

注:メンバが 'std :: unique_ptr'の場合、カスタムcopy-ctorプロビジョニングなしではコピーできません。複数のインスタンスが同じSDL_Textureを*共有する必要がある場合は、共有ポインタが適切かもしれません。 – WhozCraig

+0

別のヘッダをインクルードしないでこれを修正する方法はありますか?私がすでに書いたものを使って、好きですか?私はLazyFooのオリジナルの例から離れすぎないようにしようとしています... – WulffHunter

+0

私は投稿を更新しました。 – user3684240

関連する問題