LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 273|回复: 0

delete 运算符

[复制链接]
发表于 2024-2-4 23:30:21 | 显示全部楼层 |阅读模式
可使用 delete 运算符释放使用 new 运算符动态分配的内存。 delete 运算符调用 operator delete 函数,该函数将内存释放回可用池。 使用 delete 运算符也会导致调用类析构函数(如果存在)。

存在全局和类范围的 operator delete 函数。 只能为给定类定义一个 operator delete 函数;如果定义了该函数,它会隐藏全局 operator delete 函数。 始终为所有类型的数组调用全局 operator delete 函数。

全局 operator delete 函数。 全局 operator delete 函数和类成员 operator delete 函数存在两种形式:

void operator delete( void * );
void operator delete( void *, size_t );
给定类中只存在前面两种形式中的一个。 第一种形式采用 void * 类型的单个自变量,其中包含指向要解除分配的对象的指针。 第二个形式(大小经过调整的解除分配)采用两个自变量,第一个是指向要解除分配的内存块的指针,第二个是解除分配的字节数。 这两种形式的返回类型为 void(operator delete 无法返回值)。

第二种形式的意图是加快搜索要删除的对象的正确大小类别。 此信息通常不会存储在分配本身附近,并且可能未缓存。 当基类中的 operator delete 函数用于删除派生类的对象时,第二个形式非常有用。

operator delete 函数是静态的,因此它不能是虚拟的。 operator delete 函数服从访问控制,如成员访问控制中所述。

以下示例显示了旨在记录内存的分配和解除分配的用户定义的 operator new 和 operator delete 函数:

#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;
}
前面的代码可用于检测“内存溢出”,即在自由储存中分配但从未释放过的内存。 若要检测泄漏,应重新定义全局 new 和 delete 运算符以计算内存的分配和解除分配。

编译器在类声明中支持成员数组 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;
}

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表