C++中的new与delete可以认为是C中的malloc与free的升级版本。
new包含两部分,一部分是与malloc功能相同,是从堆上面申请内存块,第二部是调用类的构造方法来初始化刚申请的内存。
delete是new的逆过程,先调用类的析构方法来反初始化,再把刚申请的内存还给堆。
new [] 与delete []是针对数组操作符,要注意是通过new []分配的对象,不能用delete来释放对象,否则会有内存泄漏。当然通过new分配的对象,不能用delete[]来释放对象。后面我会通过代码来说明为什么。
下面是C++ 中的new与delete函数原型,申请内存失败会抛出异常bad_alloc
- void* operator new(std::size_t) throw (std::bad_alloc);
- void* operator new[](std::size_t) throw (std::bad_alloc);
- void operator delete(void*) throw();
- void operator delete[](void*) throw();
使用举例
- int* p1 = new int();
- delete p2;
- int* p2 = new int[5];
- delete [] p2;
终于到了用模板来模拟new与delete操作符,代码中有注释说明,其中对于调用类的构造方法,采用一种C++标准中称作in-place construtor的方式。使用原型为T* = new(pbuff) T(),直译的话就是在pbuff这块内存构造T类,而不用再去堆上面申请内存。这种技巧大量应用在对象池的实现中,即pbuff这块内存可以挂在链表中反复地使用(这里先不展开说了)。
- /**
- * A simulation of c++ new T() & new T(param) operation
- */
- struct NewObj
- {
- template <typename T>
- inline void operator()(T*& pObj)
- {
- // allocate memory form heap
- void * pBuff = malloc(sizeof(T));
- // call constructor
- pObj = new (pBuff) T();
- }
- template <typename T, typename P>
- inline void operator()(T*& pObj, const P& param)
- {
- // allocate memory form heap
- void * pBuff = malloc(sizeof(T));
- // call constructor, pass one param
- pObj = new(pBuff) T(param);
- }
- };
- /**
- * A simulation of c++ delete T operation
- */
- struct DeleteObj
- {
- template <typename T>
- inline void operator()(T*& pObj)
- {
- if ( NULL == pObj ) { return ;}
- // call destructor
- pObj->~T();
- // free memory to heap
- free((void*)pObj);
- pObj = NULL;
- }
- };
- /**
- * A simulation of c++ new T[N]() operation
- */
- struct NewObjArray
- {
- template <typename T>
- inline void operator()(T*& pObj, unsigned int size)
- {
- // save the number of array elements in the beginning of the space.
- long * pBuff = (long *) malloc (sizeof(T) * size + sizeof(long));
- *((unsigned int *) pBuff) = size;
- pBuff++;
- // change pointer to T type, then can use pT++
- T * pT = (T *) pBuff;
- // save the pointer to the start of the array.
- pObj = pT;
- // now iterate and construct every object in place.
- for (unsigned int i = 0; i < size; i++)
- {
- new((void *) pT) T();
- pT++;
- }
- }
- };
- /**
- * A simulation of c++ delete [] T operation
- */
- struct DeleteObjArray
- {
- template <typename T>
- inline void operator()(T*& pObj)
- {
- unsigned int size = *((unsigned int *) ((long *) pObj - 1));
- T * pT = pObj;
- // call destructor on every element in the array.
- for (unsigned int i = 0; i < size; i++)
- {
- pT->~T();
- pT++;
- }
- // free memory to heap.
- free ((void *) ((long *) pObj - 1));
- pObj = NULL;
- }
- };
测试代码
- struct TestClass
- {
- TestClass() : mem1(0), mem2(0) {}
- TestClass(int m) : mem1(m), mem2(0) {}
- int mem1;
- long mem2;
- };
- void test_new_delete()
- {
- TestClass* p1 = NULL;
- NewObj()(p1);
- printf("%p/n", p1);
- DeleteObj()(p1);
- //
- TestClass* p2 = NULL;
- NewObj()(p2, 0);
- printf("%p/n", p2);
- DeleteObj()(p2);
- //
- TestClass* p3 = NULL;
- NewObjArray()(p3, 5);
- printf("%p/n", p3);
- DeleteObjArray()(p3);
- }
Note:测试环境为eclipse+cdt+ubuntu+gcc,注意头文件需要#include <new>,使用#include <stdlib.h>会导致编译不过,因为in-place construtor是C++中的新玩意。