1
class A // blah blah generic abstracty whatever
{
  public:
  A();
  ~A();
};

class B
{
  public:
  B();
  ~B();

  private:
  A* a[8];
};

B::B()
{
  for(int x = 0; x < 8; x++)
  {
    a[x] = new A;
  }
}

B::~B()
{
  for(int x = 0; x < 8; x++)
  {
    delete a[x];
  }
}

上記のコードがそれ自体でリークするかどうかだけが気になります。(deleteを正しく呼び出さなかった場合を除いて)リークする可能性のある状況はありますか?

ありがとう。

4

4 に答える 4

9

はいnew、コンストラクターをスローする場合は可能です。

その後、デストラクタは実行されず、すでに発生した割り当ては解放されません。

具体的には、コンストラクタで例外が発生する前にメモリが動的に割り当てられている場合、オブジェクトのデストラクタが実行されないため、メモリリークが発生します。


簡単なイラスト:

class Leaks
{
private:

    data* d;

public:

    Leaks()
    {
        data = new int;
        throw 1;
    }

    ~Leaks()
    {
        delete data;
    }

};

これは欠陥のある設計です。data常にここに漏れます。それについてあなたができることは何もありません。(データが漏洩しない唯一のケースは、new失敗した場合です。)

それnew自体がスローできるため、サンプルコードは、1つ以上の割り当ての後にスローすることができ、リークが発生します。

これに対処するには、次の3つの方法があります。

  • メモリを割り当てないでください(この状況では、単にベクトルを使用しますが、動的割り当てを使用する方法がない場合もあります)
  • コンストラクターがメモリー割り当て後にスローできないこと、またはスローする前にメモリーをクリーンアップするためにスローする場合は、コンストラクターがスローできないことを確認してください。これは、最も些細なコンストラクターを除いて、かなり厄介なコードを作成します
  • スマートポインタを使用する
于 2013-03-12T06:14:39.807 に答える
1

漏れはありません。このコードは問題ありません-リークはありません。

于 2013-03-12T06:14:23.367 に答える
1

そこに漏れや潜在的な漏れは見られません。唯一の厄介なビットは、ハードコードされた配列サイズです。これを動的に変更する場合は、delete[]演算子を調べる必要があります。

于 2013-03-12T06:15:17.090 に答える
1

コードは適切なようです。漏れはありません。

于 2013-03-12T06:19:42.507 に答える