常規new和布局new

2021-07-23 10:53:41 字數 2446 閱讀 1500

通常,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物件指標作為函式引數和返回值需要手動釋放...