1

私はグラフィックアプリケーションに取り組んでいます。仮想クラスを大幅に活用します。デバッグに問題があるセグメンテーション違反が発生しています。

このアプリケーションの主要なクラスは次のとおりです。

  • Shape (仮想クラス)
    • 矩形
    • ポリゴン
    • サークル
  • 画像 (基本的には図形のコレクション)

私のコードの該当部分の短縮コピーは次のとおりです。

class Picture
{
  ...
  Picture(Graphics& gd)
  {
    gfx = &gd;
  }

  void Picture::draw() const
  {
    for(int i=0; i<shapes.size();i++)
    {
      shapes[i]->draw(*gfx);  // This line causes a segmentation fault
    }
  }
...
private:
  std::vector<Shape*> shapes;
  Graphics* gfx;
}

class Shape
{
...
virtual void draw(Graphics& g) const = 0;
...
}

以下は、いくつかの情報を示す gdb セッションです。

プログラムはシグナル 11、セグメンテーション違反で終了しました。
[新プロセス 89330 ]
#0 Rectangle::draw の 0x00020d38 (this=0x41e10, g=@0xffbff904)
    四角形で.cpp:42
42 g.setColor(getFillColor());
(gdb) &g を印刷
$1 = (クラス グラフィックス *) 0xffbff904
(gdb) ところで
#0 Rectangle::draw の 0x00020d38 (this=0x41e10, g=@0xffbff904)
    四角形で.cpp:42
#1 Picture::draw (this=0xffbff950) の 0x0001bae8 at picture.cpp:45
#2 writePicture の 0x0002394c (p=
      { = {_vptr.Figure = 0x2be38}、形状 = { >> = {_M_impl = {> = {> = {}、}、_M_start = 0x3f648、_M_finish = 0x3f664、_M_end_of_storage = 0x3f664}}、}、gfx = 0xffbff904} 、ファイル名=
        {static npos = 4294967295, _M_dataplus = {> = {> = {}, }, _M_p = 0x3f49c "t1.dat.eps"}}) testpicture.cpp:51 で
#3 simpleTest の 0x00023b3c (inFileName=
        {静的 npos = 4294967295、_M_dataplus = {> = {> = {}、}、_M_p = 0x3fe24 "t1.dat"}}、outFileName =
        {static npos = 4294967295, _M_dataplus = {> = {> = {}, }, _M_p = 0x3f49c "t1.dat.eps"}}, bb=@0xffbff9c8) testpicture.cpp:70 で
#4 main の 0x00024c3c (argc=2, argv=0xffbffa74) at testpicture.cpp:165

私はこのことを理解しようとして、数時間壁に頭をぶつけていました。これは、Picture クラスの Graphic メンバーと関係があります。ただし、それがどのように組み合わされてセグメンテーション違反が発生するかはわかりません。

編集:

これは、Graphics オブジェクトが作成される te​​stpicture.cpp の部分です。

RectangularArea getPictureBounds (string fileName)
{
  ifstream in (fileName.c_str());

  PSGraphics gr(fileName + ".bb");
  Picture p0(gr);

  Shape* shape;
  while (in >> shape)
  {
    if (shape != NULL)
      p0.add(*shape);
  }
  return p0.boundingBox();
}

グラフィックも仮想クラスです。この場合、PSGraphic はそれを継承します。

4

2 に答える 2

2

参照として与えられた引数へのポインターを保存するのは悪い習慣です。これにより、メモリの所有権について混乱が生じます。参照されたオブジェクトのコピーを作成するか (クラスの場合) 、共有リソースへのスマート ポインター( など) を取得するようにメソッドを変更します。boost::shared_ptrこのように、リソース所有権の管理は明示的です。

当面の問題に-Graphicsインスタンスはおそらくスタックに割り当てられ、スコープ外になり、破壊されます。次に、Pictureコードはデッド オブジェクトを参照します。

于 2010-03-07T03:26:02.883 に答える
2

gfx は、スタック内のオブジェクトを指します。描画しようとしているときに、オブジェクトがまだそこにある (元の位置と同じ位置にある) ことは確かですか?

于 2010-03-07T03:18:35.503 に答える