控制內存分配----重載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  版權聲明:本文爲博主原創文章,轉載請附上博文連接!

相關文章
相關標籤/搜索