c++對(duì)象內(nèi)存模型【內(nèi)存對(duì)齊】關(guān)于c++對(duì)象的內(nèi)存模型 - 【內(nèi)存對(duì)齊】方面,網(wǎng)上有大把的資料對(duì)此進(jìn)行介紹,本篇文章僅對(duì)這些內(nèi)容做一個(gè)梳理。 對(duì)齊規(guī)則,不同編譯器存在差異,,本文在“vc6/32bit”windows平臺(tái)進(jìn)行編譯測(cè)試。(缺省為8字節(jié)對(duì)齊) 0.示例代碼: 1 #pragma pack(1) // 以1字節(jié)方式對(duì)齊 2 class A1 3 { 4 char a; 5 short b; 6 }; 7 #pragma pack() // 使用缺省對(duì)齊方式 8 9 class A2 10 { 11 char a; 12 short b; 13 }; 14 15 /* 測(cè)試 */ 16 int a1 = sizeof(A1); // 3 17 int a2 = sizeof(A2); // 4 A1內(nèi)存模型(大小:3字節(jié))
A2內(nèi)存模型(大小:4字節(jié)) 1. 偽命令用法說明: #pragma pack(n) // 使用自定義n字節(jié)對(duì)齊 n可以為1,,2,,4,8,,16 #pragma pack() // 使用缺省字節(jié)對(duì)齊(缺省為8字節(jié)對(duì)齊) #pragma Pack(push) // 存放當(dāng)前字節(jié)對(duì)齊到棧頂 #pragma Pack(push, n) // 將n字節(jié)對(duì)齊方式壓入棧頂,,并啟用自定義n字節(jié)對(duì)齊方式 /*** 等價(jià)于 ***/ => #pragma Pack(push) => #pragma Pack(n) #pragma Pack(pop) // 彈出棧頂,然后啟用新棧頂字節(jié)對(duì)齊方式【彈出后,,棧為空,,則恢復(fù)為缺省字節(jié)對(duì)齊】 2. 詳細(xì)解釋: 3. 內(nèi)存對(duì)齊規(guī)則 (1)對(duì)于class(struct/union)的各個(gè)成員,第一個(gè)成員位于偏移為0的位置,,以后每個(gè)數(shù)據(jù)成員的偏移量必須是min{#pragma pack()指定的數(shù),,該數(shù)據(jù)成員的自身長(zhǎng)度} 的倍數(shù)。 (2)在數(shù)據(jù)成員完成各自對(duì)齊之后,,class(struct/union)本身也要按照min{#pragma pack()指定的數(shù),,class(struct/union)中最大基本數(shù)據(jù)成員長(zhǎng)度}進(jìn)行對(duì)齊。 4. 為什么要內(nèi)存對(duì)齊 (1)硬件限制:不是所有的硬件平臺(tái)都能訪問任意地址上的數(shù)據(jù),;某些硬件平臺(tái)只能在某些地址處取特定類型的數(shù)據(jù),,否則拋出硬件異常,。 (2)提高性能:內(nèi)存對(duì)齊后,CPU的內(nèi)存訪問速度大大提升,。 5. 那些情況要考慮內(nèi)存對(duì)齊 (1)在不同平臺(tái)之間(比如在Windows 與Linux之間),,不同模塊之間(dll與exe之間)傳遞二進(jìn)制流(比如結(jié)構(gòu)體),必須要定義相同的對(duì)齊方式,。 (2)序列化與反序列化的操作時(shí),,也必須要定義相同的對(duì)齊方式。 |
|