0

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


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

通常,重绘看起来像这样:

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 () 函数(和析构函数)之外,没有任何代码可以更改 _图像值或释放表面。

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

4

1 回答 1

1

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

  • 库构建不正确的可能性
  • 封闭的文本以某种方式被复制到代码中的其他地方(违反了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);
}
于 2013-02-13T13:17:15.800 回答