c++ - 释放有效的 SDL 表面会导致段错误

标签 c++ memory sdl memory-leaks surface

[已解决] 忘记实现复制构造函数和赋值运算符。分配给使用默认复制的实例将获得与创建它指向的表面的实例相同的指针。一旦它们中的一个析构或调用 redraw(),另一个保留指向已释放内存的指针,这会导致段错误。


我的应用程序中有一个文本标签类。当它的属性发生变化时,它会自动将自身重新绘制到它的私有(private)表面。

一般重绘是这样的:

void Text::redraw() {
 if(_font==0) return;
 if(_image) {      
  SDL_FreeSurface(_image); //this line throwing a segfault
  _image = 0;
 }

 _image = TTF_RenderUTF8_Blended(_font, _text.c_str(), _color);
}

但是代码在释放表面时崩溃(当然,只有有效的代码,因为当它没有要释放的表面时指针等于 0)。

同样奇怪的是,在某些机器上,代码运行良好并释放了内存。但在其他人身上它崩溃了。

如果我注释掉释放表面的行,应用程序运行良好,但内存泄漏。我没有找到也没有解释,也没有解决方案。


我确实在构造函数中将 _image 设置为 0。除了 redraw() 函数(和析构函数)之外,没有任何代码可以更改 _image 值或释放表面。

以某种方式释放内存仅在 XP 上崩溃。如果我注释掉释放部分,它不会崩溃。两种变体都适用于 win7(x86 和 x64)。

最佳答案

假设我们普遍知道 SDL 运行良好,这给我们留下了以下选项(我想不出任何其他选项,但很可能有一些)

  • 库构建不正确的可能性
  • 封闭的文本以某种方式被复制到代码中的其他地方(打破了rule of 3
  • 其他东西正在使用相同的指针调用 SDL_FreeSurface
  • 其他东西正在践踏堆(可能但不太可能,因为这是您所说的唯一失败的实例);

所以我通常会通过如下添加一些(grep'able)printfs 来调试它,然后逐行检查输出:

void Text::redraw() {
 if(_font==0) return;
 if(_image) {      
fprintf(stderr,"## $%x freeing $%x",this, _image);
  SDL_FreeSurface(_image);
  _image = 0;
 }

 _image = TTF_RenderUTF8_Blended(_font, _text.c_str(), _color);
fprintf(stderr,"## $%x allocated $%x",this, _image);
}

关于c++ - 释放有效的 SDL 表面会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14853601/

相关文章:

.net - 在(托管)堆栈上的托管 C++/cli 中创建的 std::vector 可能会更改内存位置吗?

javascript - 函数声明优先/覆盖变量声明?吊装?为什么?

swift - 从 Swift 创建 Unmanaged<CFString>

c++ - GLEW 初始化失败

c++ - 使用 C++ 入口点让 SDL 在 OSX 上工作

c++ - 指向 unique_ptr 的裸指针

c++ - 将 COFF lib 文件转换为 OMF 格式

c++ - 在C++中使用线程交替打印奇数和偶数打印

c++ - 我们可以创建大小为执行时常量的静态数组吗?

c++ - TEXTUREACCESSes 的解释?