通常,new負責在堆(heap)中找到乙個能夠滿足要求的記憶體塊,new操作符還有另外一種變體,稱為布局(placement)new操作符,它能夠讓你指定要使用的位置。
要使用布局new,首先要包含標頭檔案new,它後面需要乙個提供位址的引數。話不多說看**。
// newplace.cpp -- using placement new
#include
#include // for placement new
const
int buf = 512;
const
int n = 5;
char buffer[buf]; // chunk of memory
int main( )
cout
<< "\ncalling new and placement new a second time:\n";
double *pd3 , *pd4;
pd3 = new
double[n]; // find new address
pd4 = new ( buffer ) double[n]; // overwrite old data
for( i = 0; i < n; i++ )
pd4[i] = pd3[i] = 1000 + 40.0 * i;
cout
<< "memory contents:\n";
for( i = 0; i < n; i++ )
cout
<< "\ncalling new and placement new a third time:\n";
delete pd1;
pd1 = new
double[n];
pd2 = new ( buffer + n * sizeof( double ) ) double[n];
for( i = 0; i < n; i++ )
pd2[i] = pd1[i] = 1000 + 60.0 * i;
cout
<< "memory contents:\n";
for( i = 0; i < n; i++ )
delete pd1;
delete pd3;
// cin.get();
return
0;}
下面是程式的輸出(不同電腦執行結果可能不同)
我們可以看到
1:布局new確實將p2放在了buffer中,p1則是放在堆中
2:在第二次操作時,常規new查詢的是一塊新的記憶體塊,布局new分配和以前相同的記憶體,說明布局new只傳遞位址,並不跟蹤該記憶體塊是否使用過,也不查詢未使用的記憶體塊,記憶體管理的負擔交給程式猿
3:是否使用delete來釋放記憶體——對於常規new,delete [ ] pd1;釋放最初申請的記憶體,接下來再次呼叫new時該記憶體塊可用,程式並沒有使用delete來釋放布局new分配的記憶體,這個例子中不能這麼做。buffer是靜態記憶體,delete只能用於常規new分配的堆記憶體,陣列buffer位於delete的管轄區之外。當然,如果buffer是用常規new來建立的,也可以用delete釋放。
將布局new用於類物件時,情況更複雜。話不多說,先上**。
#include
#include
#include
using
namespace
std;
const
int buf = 512;
class justtesting
~justtesting( )
void show( ) const
};int main( )
非優化版本的執行結果如圖所示:
優化版本執行結果如下入所示:
對執行結果的差異做出幾點說明:
1:程式設計師想用布局new建立多個物件時,必須提供兩個不同的緩衝區位址,否則新物件會覆蓋第乙個物件的記憶體空間
2:使用布局new為物件分配記憶體時,必須確保析構函式被呼叫,但同時,我們又不能使用 delete pc1;這樣的方式來做,因此必須顯式地為使用布局new操作符建立的物件呼叫析構函式,我們刪除的時候,應當以建立順序相反的順序進行刪除,因此晚建立的物件可能依賴於早建立的物件。僅當所有物件都被銷毀後,才能釋放儲存這些物件的緩衝區。
推薦一篇博文,講得很好。
布局new操作符
通常,new負責在堆 heap 中找到乙個足以滿足需要的記憶體塊。new操作符還有另一種變體,被稱為布局new操作符,能夠讓你指定要使用的位置。程式設計師可以利用這種 要使用布局new特性,首先要包含標頭檔案new,他提供了這種new操作的原型。const int buf 512 class jus...
定位的new和new 運算子
同一作用域下的同名函式,只要引數列表不同,即可過載。過載 new和 new 運算子時,函式的第 1個引數是固定的,表示申請分配記憶體的長度。使用者在不改變第 1個引數的情況下,可以隨意增加引數,過載多個 new和 new 運算子函式。乙個比較實際的例子就是過載定位的 new和 new 運算子,即為 ...
C 用new和不用new建立類物件
1,new建立類物件,使用完後需使用delete刪除,跟申請記憶體類似。所以,new有時候又不太適合,比如在頻繁呼叫場合,使用區域性new類物件就不是個好選擇,使用全域性類物件或乙個經過初始化的全域性類指標似乎更加高效。2,非new建立類物件,建立方式,new物件指標作為函式引數和返回值需要手動釋放...