C 記憶體位置建立物件

2023-01-23 11:03:02 字數 1618 閱讀 7328

在預先定義的記憶體位置構造乙個物件

常常有人問這樣乙個c++問題:如何在預先定義的記憶體位置構造乙個物件?在預先定義的記憶體緩衝構造乙個物件有許多有用的應用。

例如,乙個定製的垃圾蒐集器能使用乙個大的預分配記憶體緩衝,使用者在這個緩衝中構造其物件。當不再需要這些物件時,它們的儲存空間被自動收回。

這個技術在重視時間的應用中也很有用。在預先分配的記憶體緩衝構造乙個物件是一種「時間常量」操作,之所以這樣說是因為程式分配操作本身不會浪費寶貴的時間。同時也要注意當系統沒有足夠的記憶體時,動態記憶體分配可能失敗。

因此,對於重視任務的應用,預先分配乙個足夠大的緩衝有時是不可避免的。

許多應用需要在給定的時間構造不同型別的物件。想一想這樣乙個例子,乙個gui應用根據使用者的輸入,每次、顯示不同的對話方塊,利用重複分配和釋放記憶體,這個應用能提前建立乙個記憶體緩衝,並能在這個緩衝裡反覆構造和銷毀不同型別的物件。

c++提供了幾種特點來方便實現在預先決定的記憶體位置構造乙個物件的任務。在這些特點中,包括乙個特殊形式的new操作符,叫做「定位new」(placement new)操作,以及乙個顯式的析構處理。實現方法如下:

第一步:分配乙個足夠的記憶體緩衝區,以便存放給定型別的物件。如果想要每次構造不同型別的物件,需要至少以最大的物件所佔空間的大小分配乙個緩衝。

預分配的緩衝是在可用記憶體空間中分配的純字元陣列。

char * buff = new char [sizeof (foo) ];

一旦分配了緩衝,就能在緩衝中構造每一種型別的物件。為此,使用特殊版本的new操作符(「定位new」),以緩衝位址為placement new的引數。為了使用placement new,必須包含標準標頭檔案。

下面的**片斷中,使用placement new操作在記憶體位址buff上構造型別為foo的物件。

#include < new >

foo * pfoo = new (buff) foo; //使用new操作在buff上構造乙個 foo

placement new 以先前分配的緩衝(buff)位址作為引數,並在這個緩衝上構造給定型別的物件。他返回構造物件的指標,這個物件指標的使用與通常的指標使用沒什麼兩樣。

unsigned int length = pfoo->size();

pfoo->resize(100, 200);

length = pfoo->size();

當不再需要這個物件的時候,必須顯式呼叫其析構函式釋放空間。做這件事是有一些技巧的,因為許多人錯誤地假設物件會被自動銷毀,錯也!。在預分配的緩衝裡構造另乙個物件之前或者在釋放緩衝之前,如果忘了顯式呼叫析構函式,程式將產生不可預料的後果。

顯式的析構器宣告如下:

pfoo->~foo(); //顯式呼叫析構函式

換句話說,乙個顯式的析構器與普通的成員函式呼叫一樣,只是名字與普通的成員函式稍有差別。一旦物件被銷毀,便可以在預分配的記憶體中再次構造另乙個物件。實際上,這個過程可以無限制地重複:

構造乙個物件,銷毀它,然後又反覆利用預分配的緩衝構造新物件。

當不再需要預定義的緩衝時,或者說當應用程式關閉時,必須釋放預定義的緩衝。使用delete完成這個任務,因為預定義的緩衝是乙個字元陣列。下列**包含乙個完整的例子的所有步驟,包括最終緩衝的釋放:

#include < new >

void placement_demo()

C 記憶體對齊

一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作...

C類和物件

1.物件導向設計簡介 1 2.物件的初始化與清除 物件賦值 6 2.1.建構函式 6 2.2.初始化成員列表 引數初始化表 9 2.3.析構函式 10 3.物件與常量 10 4.靜態成員 11 5.友員 12 5.1.友員函式 12 5.2.友員成員函式 13 5.3.友員類 13 物件導向程式設計...

c 記憶體中位元組對齊問題詳解

一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作...