0

[解決済み]コピーコンストラクターと代入演算子を実装するのを忘れました。デフォルトのコピーを使用するように割り当てられているインスタンスは、それが指すサーフェスを作成したインスタンスと同じポインタを取得します。それらの1つが破棄するか、redraw()を呼び出すと、もう1つは解放されたメモリへのポインタを保持し、セグメンテーション違反を引き起こします。


アプリケーションにテキストラベルのクラスがあります。プロパティが変更されると、自動的にプライベートサーフェスに再描画されます。

一般的に、再描画は次のようになります。

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の両方)でうまく機能します。

4

1 に答える 1

1

SDLがうまく機能することは一般的にわかっているという前提で、次のオプションがあります(他のオプションは考えられませんが、いくつかある可能性があります)

  • ライブラリが正しく構築されていない可能性
  • 囲んでいるテキストは、コード内の別の場所にコピーされています(3のルールに違反しています)
  • 他の何かが同じポインタでSDL_FreeSurfaceを呼び出しています
  • 他の何かがヒープを踏みにじっています(これは失敗すると言った唯一のインスタンスであるため、可能性はありますが、ありそうにありません)。

したがって、私は通常、次のようにいくつかの(grep可能な)printfsを追加してこれをデバッグし、出力を1行ずつ確認します。

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 に答える