【问题标题】:C++ SDL_FreeSurface crash in destructor析构函数中的 C++ SDL_FreeSurface 崩溃
【发布时间】:2012-09-29 08:17:07
【问题描述】:

我有一个类 Block 在析构函数中调用 SDL_FreeSurface(surface)。在 main() 创建 Block 的实例时,该对象正常运行,但是当我在另一个具有 vector<Block> block_vector 作为数据成员的类 Control 中使用它时,当我添加 @987654326 的实例时程序崩溃@进入block_vector。我缩小了调用SDL_FreeSurface(surface) 时Block 的析构函数的问题。向向量中添加对象与 is 有什么关系吗?有什么问题?

 class Block{

public:

    Block(int x, int y);
   ~Block();


    void Load_Image(MediaFunctions &M_Functions);

    void SetPosition(int x, int y);

    void BlitBlock(SDL_Event &event, MediaFunctions &M_Functions, SDL_Surface *destination);


    bool DetectionNames(SDL_Event &event, MediaFunctions &M_Functions, SDL_Surface *destination);

    bool DetectionHours(SDL_Event &event, MediaFunctions &M_Functions, SDL_Surface *destination);

    bool return_error();



private:


    SDL_Surface *block_surface_names;
    SDL_Surface *block_surface_hours;

    SDL_Surface *block_names_detected;
    SDL_Surface *block_hours_detected;

    SDL_Rect     block_rect_names;
    SDL_Rect     block_rect_hours;


    bool error;

    };


    //the problem
    Block::~Block(){


    SDL_FreeSurface(block_surface_hours);
    SDL_FreeSurface(block_surface_names);

    SDL_FreeSurface(block_hours_detected);
    SDL_FreeSurface(block_names_detected);

    }



    //when doing this 
    void Control::HandleEvents(SDL_Event &event, MediaFunctions &M_Functions){

if(event.type == SDL_KEYDOWN){

    if( event.key.keysym.sym == SDLK_a ){

            //append a block instance
            BlockVector.push_back(Block (Block(100,100)));
            BlockVector.at(block_index).Load_Image(M_Functions);

            block_index++;

    }

    }

    } 

【问题讨论】:

  • 您是否在验证 Block 的实例是否有效?
  • 当我从析构函数中删除 SDL_FreeSurface 时,程序运行正常。
  • @Unit978:是的,但在那种情况下它可能会泄漏SDL_Surfaces(这不是一件好事)。
  • 这就是为什么我需要知道为什么在析构函数中调用 SDL_FreeSurface 会在我将其添加到向量时导致程序崩溃。
  • 正如 Mankarse 所说,我们需要查看您的代码来识别问题。

标签: c++ vector sdl destructor


【解决方案1】:

当您将一个 Block 对象插入向量中时,会生成一个副本。由于您没有提供复制构造函数,因此使用了编译器生成的复制构造函数。编译器生成的复制构造函数将简单地复制您的指针。它不会复制实际的 SDL 表面。

这意味着您的原始 Block 对象和插入向量中的 Block 对象都具有指向相同 SDL 表面的指针。当其中一个 Block 对象的生命周期结束时,将调用析构函数,从而释放 SDL 表面。现在另一个 Block 对象有一个悬空指针,当它的生命周期结束并调用析构函数时,您在悬空指针上调用 SDL_FreeSurface。

这几乎肯定是导致您崩溃的原因。这就是为什么您需要遵循Rule of Three 并正确实现复制构造函数和赋值运算符的原因。实施取决于您。在大多数情况下,我建议对您的对象进行完整的深拷贝。但是对于像 SDL 表面这样的重量级对象,我建议您考虑实现某种引用计数机制,或者使用 std::shared_ptr 和调用 SDL_FreeSurface 而不是 delete 的自定义删除器。

【讨论】:

  • 在vector中创建对象时发生崩溃。甚至还没有调用析构函数。我添加了一个复制构造函数,但仍然发生崩溃
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
  • 2021-07-16
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 2018-01-03
相关资源
最近更新 更多