次の方法で共有


operator delete 関数

new 演算子を使用して動的に割り当てられたメモリは、delete 演算子を使用して解放できます。 delete 演算子は operator delete 関数を呼び出し、この関数がメモリを解放して使用可能なプールに戻します。 delete 演算子を使用すると、クラスのデストラクターも呼び出されます (存在する場合)。

グローバルとクラス スコープの operator delete 関数があります。 特定のクラスに対して定義できる operator delete 関数は、1 つだけです。定義されている場合、グローバルの operator delete 関数は隠されます。 グローバルの operator delete 関数は、常に任意の型の配列に対して呼び出されます。

グローバルの operator delete 関数は、宣言された場合、解放するオブジェクトへのポインターを含む void * 型の単一の引数を受け取ります。 戻り値の型は void です (operator delete は値を返せません)。 クラス メンバーの operator delete 関数には、2 つの形式が存在します。

void operator delete( void * );
void operator delete( void *, size_t );

特定のクラスに存在できるのは、上記の 2 つのバリアントのうち 1 つだけです。 最初の形式は、グローバルの operator delete の説明と同様に動作します。 2 番目の形式は 2 つの引数を取ります。最初の引数は解放するメモリ ブロックへのポインターで、2 番目は解放するバイト数です。 2 番目の形式は、基底クラスの operator delete 関数を派生クラスのオブジェクトの削除に使用するときに、特に便利です。

operator delete 関数は静的です。したがって、仮想にすることはできません。 operator delete 関数は、「メンバー アクセス コントロール」で説明されているように、アクセス制御に従います。

次の例は、メモリの割り当てと解放を記録するように設計された、ユーザー定義の operator new 関数と operator delete 関数を示しています。

使用例

// spec1_the_operator_delete_function1.cpp
// compile with: /EHsc
// arguments: 3
#include <iostream>
using namespace std;

int fLogMemory = 0;      // Perform logging (0=no; nonzero=yes)?
int cBlocksAllocated = 0;  // Count of blocks allocated.

// User-defined operator new.
void *operator new( size_t stAllocateBlock ) {
   static int fInOpNew = 0;   // Guard flag.

   if ( fLogMemory && !fInOpNew ) {
      fInOpNew = 1;
      clog << "Memory block " << ++cBlocksAllocated
          << " allocated for " << stAllocateBlock
          << " bytes\n";
      fInOpNew = 0;
   }
   return malloc( stAllocateBlock );
}

// User-defined operator delete.
void operator delete( void *pvMem ) {
   static int fInOpDelete = 0;   // Guard flag.
   if ( fLogMemory && !fInOpDelete ) {
      fInOpDelete = 1;
      clog << "Memory block " << cBlocksAllocated--
          << " deallocated\n";
      fInOpDelete = 0;
   }

   free( pvMem );
}

int main( int argc, char *argv[] ) {
   fLogMemory = 1;   // Turn logging on
   if( argc > 1 )
      for( int i = 0; i < atoi( argv[1] ); ++i ) {
         char *pMem = new char[10];
         delete[] pMem;
      }
   fLogMemory = 0;  // Turn logging off.
   return cBlocksAllocated;
}

Visual C++ 5.0 から、コンパイラはクラス宣言でのメンバー配列の new および delete 演算子をサポートします。 次に例を示します。

// spec1_the_operator_delete_function2.cpp
// compile with: /c
class X  {
public:
   void * operator new[] (size_t) {
      return 0;
   }
   void operator delete[] (void*) {}
};

void f() {
   X *pX = new X[5];
   delete [] pX;
}

コメント

上記のコードを "メモリ リーク" の検出に使うことができます。メモリ リークとは、フリー ストアに割り当てられ、解放されていないメモリを指します。 この検出を実行するため、グローバルな new 演算子と delete 演算子がメモリの割り当てと解放をカウントするように再定義されています。

参照

関連項目

operator new 関数

new 演算子 (C++)

delete 演算子 (C++)