重载类的 new,delete,new[],delete[] 运算符成员函数

1. 调用 new 时,先分配内存,后调用构造函数。调用构造函数的行为由编译器控制。
2. 调用 delete 时,先调用析构函数,后释放内存。调用析构函数的行为由编译器控制。
重载这四个运算符函数的目的是为了控制内存的分配与释放。如果需要对某个类型频繁地创建和销毁大量的对象, 这四个运算过程可能会耗费太多的时间,并且会产生内存碎片。
这四个运算符函数的原型:
  void* operator new(size_t) throw(bad_alloc);
  void operator delete(void* pmem);
  void* operator new[](size_t sz) throw(bad_alloc);
  void operator delete[](void* pmem);
重载时必须与原型一致!
请看示例代码:

#include 
#include 
#include 
#include 
#include 
#include 
using std::cout;using std::endl;using std::cerr;using std::bad_alloc;using std::hex;//void out_of_memory(){//  cerr << "memory exhausted!\n";//  exit(-1);//}template
inline void DelObject(T *&pobj){  delete pobj;  pobj = 0; // Don't forget to assigne pobj as 0.}template
inline void DelObjArray(T *&parr) {  delete []parr;  parr = 0; // Don't forget to assigne parr as 0.}class NewDelType {  union {    unsigned char ch[4];    int val;  }ts;public:  enum { psize = 10 };  static unsigned char pool[];  static bool alloc_map[];public:  NewDelType() {     ts.val = 0x12345678;      printf("%s,  this=%p, ts=(%#x,%#x,%#x,%#x,%#x)\n", __func__,this,ts.val,ts.ch[0],ts.ch[1],ts.ch[2],ts.ch[3]);  }  ~NewDelType() {      printf("%s, this=%p, ts=(%#x,%#x,%#x,%#x,%#x)\n", __func__,this,ts.val,ts.ch[0],ts.ch[1],ts.ch[2],ts.ch[3]);  }  void* operator new(size_t) throw(bad_alloc);  void operator delete(void* pmem);  void* operator new[](size_t sz) throw(bad_alloc);  void operator delete[](void* pmem);};unsigned char NewDelType::pool[psize * sizeof(NewDelType)];bool NewDelType::alloc_map[psize] = {false};void* NewDelType::operator new(size_t) throw(bad_alloc) {  for(int i = 0; i < psize; i++){    if(!alloc_map[i]) {       printf("%s, to use block %d\n", __func__, i);      alloc_map[i] = true; // Mark it used      return pool + (i * sizeof(NewDelType));    }  }  printf("%s, to throw bad_alloc\n", __func__);  throw bad_alloc();}void NewDelType::operator delete(void* pmem) {  // Check for null pointer  if(!pmem){    printf("%s, null pointer\n", __func__);    return;  }  // Assume it was created in the pool  // Calculate which block number it is:  unsigned long block = (unsigned long)pmem - (unsigned long)pool;  block /= sizeof(NewDelType);  printf("%s, freeing block:(%p, %lu)\n", __func__, pmem, block);  assert(block >= 0 && block < psize && alloc_map[block] == true);  // Mark it free:  alloc_map[block] = false;}void* NewDelType::operator new[](size_t sz) throw(bad_alloc) {  assert( (sz - 8) % sizeof(NewDelType) == 0);  int request = (sz - 8) / sizeof(NewDelType);  assert(request >= 0 && request <= psize);  printf("%s, sz = %lu, reqest = %d\n", __func__, sz, request);  int avail = 0;  int start = -1, end = -1;  for(int i = 0; i < psize; ++i){    if(alloc_map[i] == false)      ++avail;    else      avail = 0;    if(avail == request){      end = i;      start = end + 1 - request;      break;    }  }  if(avail == request){    for(int j = start; j <= end; ++j){      alloc_map[j] = true;     }    unsigned char *pbyte =  pool + start * sizeof(NewDelType);    printf("%s, to use block:(%p, %d, %d)\n", __func__, pbyte, start, end);    printf("\t");    for(int k = 0; k < 12; ++k){      printf("0x%x ", pbyte[k]);    }    printf("\n");    return pbyte;  }  else{    printf("%s, to throw bad_alloc, avail = %d\n", __func__, avail);    throw bad_alloc();  }}void NewDelType::operator delete[](void* pmem) {  // Check for null pointer  if(!pmem){    printf("%s, null pointer\n", __func__);    return;  }  //The quantity of objects allocated was saved in the first byte.  //WARNING: Maybe the quantity is not saved here for every case.   unsigned char to_free = *(unsigned char *)pmem;  printf("%s, pmem:(%p, %d)\n", __func__, pmem, to_free);  printf("\t");  unsigned char *pbyte = (unsigned char *)pmem;  for(int k = 0; k < 12; ++k){    printf("0x%x ", pbyte[k]);  }  printf("\n");  unsigned long block = (unsigned long)pmem - (unsigned long)pool;  block /= sizeof(NewDelType);  int start = block;  int end = block + to_free - 1;  assert(start >= 0 && end < psize);  printf("%s, freeing block: (%d, %d)\n", __func__, start, end);  // Mark it free:  for(int i = start; i <= end; ++i){    assert(alloc_map[i] == true);    alloc_map[i] = false;  }}int main() {  NewDelType *pobj1 = 0, *pobj2 = 0, *pobj3 = 0, *pobj4 = 0;  printf("%s, NewDelType::pool:(%p ~ %p)\n", __func__, NewDelType::pool, NewDelType::pool + sizeof(NewDelType::pool) - 1);  //set_new_handler(out_of_memory);  try {    pobj1 = new NewDelType;//    DelObject
(pobj1);    cout << endl;    pobj2 = new NewDelType[9];    DelObjArray
(pobj2);    cout << endl;//    pobj3 = new NewDelType[5];//    cout << endl;////    pobj4 = new NewDelType[6];  } catch(bad_alloc &) {    cerr << __func__ << ", Out of memory!" << endl;  }}

测试结果:

main, NewDelType::pool:(0x6023a0 ~ 0x6023c7)

operator new, to use block 0
NewDelType,  this=0x6023a0, ts=(0x12345678,0x78,0x56,0x34,0x12)

operator new [], sz = 44, reqest = 9

operator new [], to use block:(0x6023a4, 1, 9)
        0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
NewDelType,  this=0x6023ac, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023b0, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023b4, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023b8, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023bc, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023c0, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023c4, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023c8, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023cc, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023cc, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023c8, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023c4, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023c0, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023bc, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023b8, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023b4, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023b0, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023ac, ts=(0x12345678,0x78,0x56,0x34,0x12)
operator delete [], pmem:(0x6023a4, 9)
        0x9 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x78 0x56 0x34 0x12
operator delete [], freeing block: (1, 9)