2

次のコードを検討してください。

#include "iostream"
#include "conio.h"

using namespace std;

class sample
{
      private:
              int i;
      public:
             sample(int ii=0) : i(ii){                         
                   cout<<"Constructing Object"<<endl; 
                   }

             ~sample() { cout<<"Destructing Object"<<endl; }

             void* operator new(size_t nSize, void* loc){
                   cout <<"Inside new"<<endl;
                   cout <<loc<<endl;
                   return loc;
                   }

             void operator delete(void* ptr){
                  cout <<"Inside delete"<<endl;
                  free(ptr);
                  }
};


int main()
{
    int intArr[2];
    sample* samplePtr = new(intArr) sample(5);
    cout <<samplePtr<<endl;

    delete samplePtr;  
//    samplePtr->sample::~sample();
    getch();
}

出力:

Inside New
0x22ff38
Constructing Object
0x22ff38
Destructing Object
Inside Delete

ここでは、すでにスタックに割り当てられているメモリを動的に要求しています。完了したら、デストラクタを明示的に呼び出す必要があることを読みました。しかし、スタックに割り当てられたメモリに対してdeleteを呼び出そうとすると、デストラクタが呼び出されます。これは、デストラクタが呼び出された後にスタック上のメモリが解放されることを意味しますか?

以前にヒープに割り当てられたメモリを動的に要求する場合、その場合はdeleteを呼び出す必要がありますが、deleteは実際にスタック上のメモリを解放しますか?

4

3 に答える 3

14

通常の new 演算子は次の 2 つのことを行います。

  1. 動的メモリ マネージャーを呼び出して、メモリのチャンクを取得します
  2. コンストラクターを呼び出します

通常の削除演算子は逆のことを行います

  1. デストラクタを呼び出す
  2. 動的メモリ マネージャーを呼び出して、メモリのチャンクを解放します

Placement new は 1 つのステップのみを実行します。

  1. コンストラクターを呼び出します

したがって、「プレースメントの削除」は次の 1 つの手順で行う必要があります。

  1. デストラクタを呼び出す

行ったように、新しい配置の後に通常の削除を呼び出すべきではありません。(その理由は、そうすると、動的メモリ マネージャーが割り当てられていないブロックを削除するように要求され、未定義の動作が発生するためです)

この行は間違っています:

delete samplePtr;  // WRONG

「配置の削除」を行う必要があります。これは、記述子の生の呼び出しです。

samplePtr->~sample(); // CORRECT
于 2012-03-27T11:31:25.290 に答える
1

あなたがしていること(freeによって割り当てられなかった空きメモリmalloc)は、未定義の動作を引き起こします-何かが起こる可能性があります。delete経由で取得されなかったポインターを ing する場合と同じnewです。またはその逆deleteから取得したポインターを ing する場合と同じです。malloc

「機能する」ように見えるからといって、それが正しいとは限りません。freeメモリをスタックしてはなりません。この場合、デストラクタを直接呼び出す必要があることは正しいです。

于 2012-03-27T11:31:45.057 に答える
0

これが、 new の配置が悪い可能性がある理由です (実際、可能であればそれを避ける必要があります。この場合は、objectを単にスタック割り当てするだけです) 。する必要がありますdeletenewsamplePtr->~sample();

于 2012-03-27T11:34:03.970 に答える