基本元素
new
operator new
placement new
array new
一.new和operator new
1.new expression 的操作伪代码
complex * pc = new complex(1,2)
try{
void * mem = operator new(sizeof (complex)); // operator new可以被重载,没有重载的话,调用全局的::operator new
pc = static_cast<complex*>(mem);
pc->complex::complex(1,2); //直接调用 构造函数,部分编译器才可以做的操作
//或者调用 new(p) Complex(1,2) placement new
}
catch(std::bad_alloc){
}
2.operator new的全局版本 (vc版本)
operator new (size_t size,std::nothrow_t &) _THROW0{
void *P;
while((p = malloc(size) == 0){
_TRY_BEGIN
if(callnewh(size) == 0 ) break; //callnweh由用户自己设定,可能可以释放一些觉得不重要的内存这样在下次malloc中可能可以成功
_CATCH(astd::bad_alloc) return(0);
_CATCH_END
})
}
- 第一个参数“必须”是size_t,以接受new expression的以sizeof(T)为实参的调用
- callnewh(size) 由用户自己设定,可能可以释放一些觉得不重要的内存这样在下次malloc中可能可以成功
- std::nothrow_t & 保证这个函数不抛出异常,指明这个函数通过返回一个空指针来表明分配失败,而不是抛出异常
3.delete expression
pc-> ~ Complex();
operator delete(pc);
4.array new
int * pi = new int[10] 的内存空间 (默认行为下的内存空间)

- delete[] 会调用多次析构函数,如果对一个管理堆内存的对象来说会有影响。
- delete 把指针指向的位置当成一个对象去解析,只会调用一次析构函数,所以并不会造成内存泄漏
- 必须要有默认构造函数,array没机会给掉带参数的
- new[]从地地址向高地址new, delete[] 从高地址向低地址delete
- Debugger Header 在debug模式下出现
- 头和尾有个cookie,记录整个分配空间的大小(malloc行为,每一次都会有)
- 内存要16字节对齐,所以添加了 12个字节的填补
二.placement new
1.placement new
处理流程和new expression一样
区别在于对于operator new的调用上
string s;
string* s= new(&s) string("a");
调用void* operator new(size_t,void * start) { return start ;}
string s;
string* s= new(300) string("a");
调用void* operator new(size_t len,size_t extra) { malloc(len+extra) ;}
- palcement new中调用operator new时,第一个参数是sizeof的值,之后再传递placement new接受的参数
1.placement delete的重载
placement delete的重载可以被自动调用。
每一个new操作都有分配内存,类型转换,调用构造三步操作
如果在调用构造时抛出异常,为了不让之前的分配出的内存泄漏,会自动调用与之对应的operator new的重载形式
operator new(size_size ,long) 会自动调用 void operator delete(void * ,long)
operator new(size_size ) 会自动调用 void operator delete(void *)
如果没有找到对应的重载, 则被视为放弃处理
网友评论