定位new運算子

2021-10-06 11:43:27 字數 3513 閱讀 4827

在c/c++語言中,void*是虛無的,任意的,也就是可以用來強制轉換任意的指標型別,比如說

char base[4] = ;

cout << base << endl;

cout << (void*)base << endl;

執行結果如下:

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-mb62hovy-1590411769396)(qq截圖20191209163528.jp)]

很簡單的**,列印abc字串,但是base是char 型別,列印的確是整個字串,而不是乙個指標型別,原因是ostream類裡面就是這樣設定的,如何轉換成指標型別就用到了void進行強制轉換.

new的一種常用的用法就是給某一變數或者物件從堆中分配空間,還有一種用法就是在指定要使用的位置分配空間,比如乙個靜態陣列,這種方法就是定位new,他的方法是包含在new這個檔案中:

#include

char buffer[50]

;double

* base =

new(buffer)

double[5

];

以上語句就是從buffer第一塊記憶體開始占有5 * sizeof(double)個記憶體塊的空間,注意這裡並沒有語法錯誤,雖然是double型別的指標,但的確可以利用已經存在的buffer陣列的靜態空間.

分析下列**:

#include

#include

// for placement new

const

int buf =

512;

const

int n =5;

char buffer[buf]

;// 一塊靜態空間的**

intmain()

cout <<

"\ncalling new and placement new a second time:\n"

;double

*pd3,

*pd4;

pd3=

newdouble

[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=

newdouble

[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;

return0;

}

執行結果如下:

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-7byldaun-1590411769400)(qq截圖20191209154518.jpg)]

可以發現每次使用定位new運算子都是從buffer陣列這塊空間一開始分配.而且可以使用

pd2 =

new(buffer + n *

sizeof

(double))

double

[n];

以上語句改變偏移量.

pd1和pd3所指空間是從堆中分配的,沒有從已經存在的空間中分配,可以通過delete刪除,但是無法刪除pd2和pd4所指空間,因為這兩個都是已經存在的靜態空間,或者說靜態陣列buffer不屬於delete管.

執行結果如下:

#include

#include

#include

using

namespace std;

const

int buf =

512;

class

justtesting

~justtesting()

// 析構函式

void

show()

const

// 顯示物件內容};

intmain()

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-dj3bdbcz-1590411769404)(qq截圖20191209155132.jpg)]

注意兩點 :

如果兩個物件使用同乙個緩衝區的,就要注意不要將後乙個物件覆蓋掉前乙個物件的空間,應當修改如下,將偏移量往後移乙個物件的大小

pc3 =

new(buffer +

sizeof

(justtesting)

);

不能夠直接用delete刪除緩衝的空間,如delete pc1;delete pc3,因為delete是和常規new配合使用的,不能跟定位new運算子配合使用.

但是delete buffer確實是釋放了buffer的空間,但是卻沒有呼叫pc1和pc3的析構函式,解決方法就是主動呼叫析構函式,注意順序,一般都是後建立的先呼叫析構函式.這也是為數不多主動呼叫析構函式的情況,一般都是自動呼叫.

pc3-

>

~justtesting()

; pc1-

>

~justtesting()

;

在原來的基礎上改善的的**如下:

#include

#include

#include

using

namespace std;

const

int buf =

512;

class

justtesting

~justtesting()

void

show()

const};

intmain()

定位new運算子

通常,new 從堆中分配記憶體,但它還有另一種稱為 定位 placement new 運算子,它可以讓我們指定要使用的位置。可以通過這個特性來設定記憶體管 理規程,處理需要通過特定位址進行訪問的硬體或在特定位置建立物件。要使用定位 new 特性,需要包含標頭檔案 new。使用定位 new 運算子時,...

定位 new 運算子

定位 new 運算子 和普通的new 運算子在堆上隨機分配記憶體相比,定位 new 運算子可以在特定的位址位置 定位 new 運算子的具體使用例項 const int buf 512 const int n 5 char buffer buf void part9 newplace 定位new 的其...

定位new運算子

一般的new運算子負責在heap堆中找到乙個足以能夠滿足要求的記憶體塊。定位new運算子在標頭檔案中。定位new運算子直接使用傳遞給它的位址,它不負責判斷哪些記憶體單元已被使用,也不查詢未使用的記憶體塊。這將一些記憶體管理的負擔交給了程式設計師。下面用乙個簡單的程式來說明定位new的用法 inclu...