2016-12-22 3 views
-2

Я пытаюсь реализовать простой пример кода с цветовым ключом, основанный на удивительных учебниках LazyFoo (http://lazyfoo.net/tutorials/SDL/10_color_keying/index.php), но когда я пытаюсь запустить его, поток дает мне EXC_BAD_ACCESS (code = 1, address = 0x0) на указателе, несмотря на то, что я пытаюсь проверить, является ли этот указатель нулевым или нет. Вот что класс выглядит следующим образом:EXC_BAD_ACCESS, когда я пытаюсь проверить NULL

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

и вот инициализировать и уничтожить методы:

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

Я не понимаю ... где бы я копировал текстуру? Я думал, что бесплатное() будет неважно, скопирована ли текстура или нет? – WulffHunter

+1

Это не то, что он имел в виду. 1. Поместите 'LTexture (const LTexture &) = delete;' в определение вашего класса. 2. Скомпилируйте, и вы скоро увидите места, в которых вы копируете экземпляры вашего класса объектов (потому что они больше не могут этого делать). См. [Правило три] (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; 

Вы можете удалить свой деструктор.

Edit: Если вы действительно не хотите использовать <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

Есть ли способ исправить это без '# include' с другим заголовком? Например, используя материал, который я уже написал? Я стараюсь не заходить слишком далеко от оригинальных примеров LazyFoo ... – WulffHunter

+0

Я обновил сообщение. – user3684240