在實際應用中,遇到這樣的情況:已分配好了一塊記憶體,需要在這塊記憶體上面分配乙個類物件。這時可以通過強制型別轉換,把該記憶體塊強制轉換成類物件:
class a{};
char *p = new char[100];
a *pa = reinterpret_cast(p);
但是,這樣轉換的話,類的建構函式就沒有得到呼叫,類成員變數就沒有被初始化。
這個時候我們可以使用placement new來操作:
#include
using namespace std;
#pragma pack(push, 1)
class ctest
ctest(char *pszstr)
~ctest()
void setstring(const char *pszstr)
void printf() const;
private:
char *m_ptest;
char m_ctest;
};#pragma pack(pop)
int main()
;char *p = new char[nlength*100+40];
ctest *pt1 = new (p) ctest("pt1"); // a行,該呼叫即為placement new
ctest *pt2 = new (szbuf) ctest("pt2");
pt1->printf();
pt1->~ctest(); // 與a行配對使用,釋放物件中建立的資源
pt2->pritf();
pt2->~ctest();
delete p;
::system("pause");
//_crtdumpmemoryleaks();
return 0;
}何謂placement new? placement new是過載operator new 的乙個標準、全域性的版本,它不能夠被自定義的版本代替(不像普通版本的 operator new 和 operator delete能夠被替換)。
placement new的作用主要就是在乙個已存在(分配好的)記憶體塊上面分配乙個物件,placement new的使用方法:
a、建立乙個記憶體塊,該記憶體塊可以是棧上的,也可以是堆裡面的:
char *p = new char[1000];
char szbuf[1000];
b、在已知記憶體塊上面建立物件:
ctest pt1 = new (p) ctest("pt1");
ctest pt2 = new (szbuf) ctest("pt2");
c、顯式呼叫物件的析構函式釋放物件中構造的資料:
pt1->~ctest();
pt2->~ctest();
d、釋放記憶體塊(如果需要):
delete p;
使用placement new時,需要注意的是,當建立陣列物件時,需要注意物件的開始位置:在物件開始位置之前,還會有乙個int長度的記憶體用來儲存陣列物件的長度:
int main()
利用debug->windows->memory觀察視窗觀察下相關指標所指向記憶體中的資料就可以看得明明白白了。
如果上面char *p = new char[nlength*5+16];中的16去掉,直接:
char *p = new char[nlength*5];
ctest *pt1 = new (p) ctest[5]; // 記憶體操作越界了。
那麼delete p的時候就會報錯了:heap corruption detected.因為new (p) ctest[5];這個操作所操作的記憶體超過
p的有效範圍了。
C placement new 用法舉例
在處理記憶體分配的時候,c 程式設計師會用 new 操作符 operator new 來分配記憶體,並用 delete 操作符 operator delete 來釋放記憶體。這是乙個 new 操作符的例子。class ctest 分配乙個物件 ctest ptest new test 分配乙個有十個...
使用GraphEdit使用
1 註冊元件。其實乙個filter就是乙個com元件,所以使用之前需要註冊,可以有兩種方法對元件進行註冊。1.直接使用命令。命令列下輸入 regsvr32 hqtlystd.ax 編譯之後你會在工程目錄下的debug中找到hqtlystd.ax,這個就是要用的filter 即可註冊成功。2.vc6....
MySQL使用學習使用 mysql學習使用
1 mysql學習 1 安裝 ubuntu下直接安裝 apt get install mysql server 2 檢查伺服器是否啟動 sudo netstat tap grep mysql,如果啟動成功,出現以下資訊 tcp00localhost.localdomain mysql listen ...