统。
如:
void* buffer=operator new (50*sizeof(char));//分配内存,放置50个char,没有调用构造函数
...
operator delete(buffer); //释放内存,而没有直接调用析构函数。
这组行为类似malloc和free。
如果使用了placement new ,在某块内存中产生对象,你应该避免那块内存使用delete operator(操作符)。
因为delete operator会调用operator delete来释放内存,但是该内存所含的对象最初并不是由operator new 分配来的。
placement new只是返回它接收的指针而已,谁知道那个指针从哪里来呢?
所以为了抵消该对象的构造函数的影响,使用placement new 时应该直接调用该对象的析构函数。
请看示例:
void * mallocShared(size_t size);//申请分配内存
void freeShared(void * momery);//释放内存
void* sharedMemory=mallocShared(sizeof(Widget));
Widget *pw=constructWidgetBuffer(sharedMemory,10);//使用前面Widget类的placement new
...
delete pw;//无定义,因为sharedMemory来自mallocShared,不是来自new
pw->~Widget();//OK,析构函数pw所指Widget对象,但并释放Widget所占用内存。
freeShared(pw);//OK,释放pw所指的内存,不调用任何析构函数。
如上述所示,如果交给placement new的原始内存(raw memory)本身是动态分配而得的,那么最终得释放那块内存,以避免memory leak
更详细分析请参见《Counting Objects in C++》
数组(Arrays)
前面所做的都是基于单一对象上的,如果是一组对象呢?
string *ps=new string[10];//分配一个对象数组
1.这里的new 与前面的new 行为类似,但略有不同,这里不能再operator new分配内存,而是以operator new[]负责分配。
和operator new 一样,operator new[]也可以被重载。
注:operator new[]是相当晚的时候才加入
C++的一个特性,所以你的编译器不一定能支持它。如果是这样,全局的operator new 会被用来为每一个数组分配内存(不论数组中的对象是什么类型)。在这样的编译器下定制“数组内存分配行为”很困难,因为你得改写全局的operator new才行。默认情况下,全局版的operator new 负责程序中所有的动态内存分配,所以其行为的任何改变都可能带来全局的影响。
另外,前面讲过,operator new 只允许size_t一个参数。所以你如果决定声明为自己的函数,你的程序便不兼容于任何做了相同决定的程序库。
多方面考虑之下,如果编译器不支持operator new[],定制数组内存管理行为,不是一个明智的决定。
2.数组的new 与单一对象的new所调用的构造函数不同,数组的new 必须针对数组中每一个对象调用一个构造函数。
string *ps=new string[10];//调用operator new[]以分配足够容纳10个string对象的内存,然后针对每个元素调用string的默认构造函数。
同样的,当使用了delete,它