控制内存分配----重载new和delete & 定位new表达式

文章来源C++  Primer 第五版ios

重载new和delete程序员


注:express

了解operate new和operate delete各自的功能;
析构函数只是销毁对象,而不会释放掉内存,这也就解释了delete表达式为何是执行了两步。函数

关于noexcept有关知识,请参考<http://blog.csdn.net/qianqin_2014/article/details/51321631>性能


定位new表达式spa

关于allocator的知识,请参考<http://blog.csdn.net/qianqin_2014/article/details/51323555>.net

定位new表达式的应用指针

1 经典示例:
#include <iostream>
#include <new>
const intchunk = 16;
class Foo
{
public :
int val( ) { return _val; }
Foo( ) { _val = 0; }
private :
int_val;
};
//预分配内存,但没有Foo对象
char*buf = new char[ sizeof(Foo) * chunk ];
int
main( void )
{
//在buf中建立一个Foo对象
Foo*pb = new (buf) Foo;
//检查一个对象是否被放在buf中
if ( pb->val() == 0 )
{
cout <<"new expressio worked!" <<endl;
}
//到这里不能再使用pb
delete[] buf;
return 0;
}对象

但我不了解这种“定位new表达式”相对于通常的new的优势是什么?它的用法比通常的new对象要复杂!blog

2使用定位new表达式做用

1)placement new的做用就是:建立对象可是不分配内存,而是在已有的内存块上面建立对象。用于须要反复 建立并删除的对象上,能够下降分配释放内存的性能消耗。

2)定位new表达式,容许程序员将对象建立在已经被分配好的内存中,new表的式的形式以下:
new (place_address) type
new (palce_address) type (initializer-list)

place_address必须是个指针,指向已经分配好的内存。为了使用这种形式的new表达式,必须包含头文件<new>。

定位new表达式不能调用delete删除 placement new的对象,须要人为的调用对象的析构函数,而且人为的释放掉占用的内存。

#include <iostream> 
#include <new> 
 
 
using namespace std; 
 
const int chunk = 16; 
 
class Foo 

public: 
int val(){return _val;} 
Foo(){_val=0;} 
private: 
int _val; 
}; 
 
int main() 

// 预分配内存buf 
 
char *buf = new char[sizeof(Foo) * chunk]; 
 
// 在buf中建立一个Foo对象
 
Foo *pb=new (buf) Foo; 
// 检查一个对象是否被放在buf中
 
if(pb->val()==0) cout<<"new expression worked!"<<endl; 
// 这里不存在与定位new表达式匹配的delete表达式,即:delete pb, 其实只是为了
// 释放内存的话,咱们不须要这样的表达式,由于定位new表达式并不分配内存。
// 若是在析构函数中要作一些其余的操做呢?就要显示的调用析构函数。
// 当程序再也不须要buf时,buf指向的内存被删除,它所包含的任何对象的生命期也就
// 都结束了。 
 
delete[] buf; 
return 0; 
}

定位new表达式的应用:
在咱们的程序中,首先使用malloc为对象分配空间,而后经过定位new表达式将对象建立在已经被分配好的内存中,完成构造函数的调用。

3)
“new (start) Screen;”

这是定位new操做

Screen *ps = new (start) Screen;

表示在已经开辟好的内存区start中为堆对象Screen申请一个内存

也就是说,若是start占100个字节,你如今从它的第1个字节开始,往里面写入Screen,这样作从此要释放内存的时候有麻烦,若是Screen里面有指针,并开辟了空间,那么delete ps会调用析构函 数,然而在释放指针变量所占的内存空间时也释放了为对象所分配的内存空间,因此start中的那块内存也丢失了,由于ps也指向了start.因此要避免这种状况,就要先ps->~Screen()这样显示的调用Screen的析构函数,再delete []start。 ---------------------  做者:烽火前秦路  来源:CSDN  原文:https://blog.csdn.net/qianqin_2014/article/details/51320775  版权声明:本文为博主原创文章,转载请附上博文连接!

相关文章
相关标签/搜索