3

この質問は一部の人には単純すぎるように聞こえるかもしれませんが、 delete キーワードを使用して動的に割り当てられたブロックを持つオブジェクトを削除するとどうなるかを理解しようとしています。

delete を呼び出すと、2 つのことが行われます。最初にデストラクタを呼び出し、次にメモリを解放します。削除がオブジェクトメモリを解放している場合、動的に割り当てられたメモリも解放されますか、実際にメモリブロックを安全に解放するには、デストラクタにコードのブロックを記述する必要があります。

また、オブジェクトがヒープにメモリを割り当てられている場合、メンバー変数以外のものがオブジェクトに割り当てられたメモリを占有します。

前もって感謝します

4

5 に答える 5

4

あなたがこのようなものを持っているなら:

class Foo
{
public:
   int* block;

   Foo()
   {
       block = new int[10];
   }

private:
   Foo(const Foo&);
   Foo& operator =(const Foo&);
};

その後、これを行います。

Foo* foo = new Foo;
delete foo;

そうです、あなたはメモリリークを起こしているのです。Fooオブジェクトの動的ブロックが解放されることはありません。これを解放するデストラクタを使用してこれに対処できます。(ソースの場合、クラス宣言でもデストラクタを宣言する必要があります):

Foo::~Foo()
{
    delete [] block;
}

2つのことをすることをお勧めします

  1. 削除と新規をカウントします。それらが同じでない場合、それは一般的に問題です。
  2. C++での動的ポインタとメモリ使用量に関するこの有益なドキュメントをお読みください。

#2に続いて、ところで、これに似たオブジェクトが得られる可能性があります。

class Foo
{
public:
   std::array<int,10> block;

   Foo() // note: default-construction of `block`
   {
   }

   // note: default *destructor* will clean up member variables
   //  by firing their destructors for you. in this case the destructor
   //  for our 'block' member is a std::array that knows how to self-clean.

   // note: we no longer have to hide or implement copy construction and
   //  assignment operator functionality. The default implementation of 
   //  these properly member-copy and member-assign respectively.
};

そして、このような使用法(多くの可能性の1つ):

std::unique_ptr<Foo> foo(new Foo);

最後の例のソースにあるメモを考慮してください。自己管理メンバーを練習するクラスを使用することにより、メモリ管理の肩から大きな重みが取り除かれます。その重みを持ち上げると、メモリリーク、浅いコピーの危険など、それに関連するバグが発生する可能性も高くなります。

于 2012-12-30T01:01:06.157 に答える
1

動的に割り当てられたブロックを操作するには、delete[]を呼び出す必要があります。

例えば:

class C
{
    //some members
public:
    C() {...}
    ~C() {...} 
    // some methods
};

int main()
{
C * arr = new C[10]; // Dynamically allocated memory

// some code using arr . . .

delete[] arr; // Calling ~C() for each C element in arr and then releasing the dynamically alloacted memory on the heap pointed by arr.
}

ただし、さらに動的に割り当てられたメンバーポインターがある場合は、オブジェクトのデストラクタでそれを削除する必要があります。

C::C()
: memberArray(new int[10]) {  }

C::~C()
{
   delete[] memberArray;
   memberArray = NULL;
}
于 2012-12-30T01:02:40.530 に答える
1

呼び出すときに解放されるメモリdeleteは、オブジェクト自体が占有するメモリだけです。オブジェクトは多数の連続したバイトを占有し、それらは で解放されdeleteます。 sizeof(MyType)何バイトか表示されます。によってリリースされるものは他にありませdeleteん。それ以外はすべて、デストラクタ (または個々のメンバー オブジェクトのデストラクタ) によって解放されます。

于 2012-12-30T00:52:21.660 に答える
0

deleteデストラクタの使用法は、デストラクタに含まれる各ポインタ属性のステートメントを呼び出すことです。たとえば、ポインターである属性「タイヤ」を持つクラス「車」がある場合、車のデストラクタでこの属性を削除する必要があります。

于 2012-12-30T00:52:15.497 に答える
0

いいえ、割り当てられたメモリは解放されません。

動的メモリを割り当て、それをポインタに割り当てたオブジェクトが削除されると、ポインタのみが解放され、それが指しているデータは解放されません。オブジェクトがメモリを割り当てた場合、デストラクタでそのデータの削除を手動で呼び出すか、そのデータへのポインタを取得した他のオブジェクトによって削除されていることを確認する必要があります

割り当てオブジェクトが削除された後、オブジェクトは割り当てられたデータを別のオブジェクトに渡し、そのオブジェクトがまだそれを必要としている可能性があるため、自動的に削除することは不可能です。

于 2012-12-30T00:53:18.023 に答える