溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C++內(nèi)存對齊怎么理解

發(fā)布時間:2021-11-30 17:56:30 來源:億速云 閱讀:178 作者:iii 欄目:編程語言

這篇文章主要講解了“C++內(nèi)存對齊怎么理解”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++內(nèi)存對齊怎么理解”吧!

一、為什么要內(nèi)存對齊?

訪問未對齊的內(nèi)存,處理器要訪問兩次(數(shù)據(jù)先讀高位,再度地位),訪問對齊的內(nèi)存,處理器只要訪問一次,為了提高處理器讀取數(shù)據(jù)的效率,我們使用內(nèi)存對齊。Windows 默認對齊數(shù)為8字節(jié),Linux 默認對齊數(shù)為4字節(jié)。

使用內(nèi)存對齊的原因還有平臺的原因:不是所有的硬件平臺都能訪問特定的地址上的任意數(shù)據(jù),某些平臺只能訪問特定的地址上的獲取數(shù)據(jù),否則會拋出異常。

二、內(nèi)存對齊原則:

在內(nèi)存中,編譯器按照成員列表分別為 每個結(jié)構(gòu)體變量分配內(nèi)存,當存儲過程中需要對齊的需求時,編譯器會在成員之間留下額外的內(nèi)存空間。如果想要確認結(jié)構(gòu)體占多少存儲空間,則使用關(guān)鍵字sizeof查看大小,如果想得知結(jié)構(gòu)體的某個特定成員在結(jié)構(gòu)體的位置,則使用offsetof(頭文件stddef.h)

結(jié)構(gòu)體或聯(lián)合體的數(shù)據(jù)成員、第一個成員放到0片便宜的地方,以后每個數(shù)據(jù)成員放到自身對齊的整數(shù)倍偏移處。(對齊數(shù)是變量自身大小和默認對齊數(shù)的較小值)結(jié)構(gòu)體的大小必須是最大對齊數(shù)的整數(shù)倍。

三、對于結(jié)構(gòu)體字節(jié)對齊,有哪些規(guī)則?

總體上我們假設(shè)結(jié)構(gòu)體起始位置為0x0000,N為設(shè)置的n字節(jié)對齊,則滿足公式0x0000%N==0,來決定結(jié)構(gòu)體成員存儲的位置。

1.如果是采用默認對齊規(guī)則,需要執(zhí)行以下的步驟:

(1)結(jié)構(gòu)體的成員的自身對值N(數(shù)據(jù)類型占有的空間,比如在32位機器下int型為4字節(jié),自身對值為4)需要與存儲位置做出判斷。若滿足“起始位置%N=0”(除了結(jié)構(gòu)體的第一個成員,N也要必須滿足>=成員自身對齊值),則把該成員存放在該起始位置。若前一個成員與目前成員的存儲位置有一定的距離,則把該距離作為填充空間。

(2)所有結(jié)構(gòu)體的成員都分配完存儲位置之后,則還要結(jié)構(gòu)體本身也要進行對齊。結(jié)構(gòu)體本身也要滿足“(M+X)%S=0”來進行對齊,其中M+X是整個結(jié)構(gòu)體占有的存儲空間大小,M是所有結(jié)構(gòu)體的成員的存儲空間大小總和,X是為了滿足S的整數(shù)倍的填補空間大小,S是就是結(jié)構(gòu)體成員中自身對齊值最大的那個。

四、如果是采用#pragma pack(N)規(guī)則,需要執(zhí)行以下的步驟:

(1)結(jié)構(gòu)體成員的自身對齊值是偏移的量。若滿足“起始位置%N=0”(這里N是指定對齊值,即#pragma pack(N)),則可以把該成員存儲到該起始位置中,偏移量為該成員的自身對齊值(比如int型自身對齊值為4,占用4個字節(jié)的內(nèi)存位置)。

(2)結(jié)構(gòu)體自身對齊值為該結(jié)構(gòu)體的所有成員自身對齊值中最大的值,但又因為結(jié)構(gòu)體的有效對齊值(即指定對齊值)為N,所以“(M+X)%N=0”,M+X是該結(jié)構(gòu)體存儲的空間大小。

五、為什么我的編譯器在結(jié)構(gòu)中留下了空洞?這導致空間浪費而且無法與外部數(shù)據(jù)文件進行“二進制”讀寫。能否關(guān)掉填充,或者控制結(jié)構(gòu)域的對齊方式?

當內(nèi)存中的值合理對齊時,很多機器都能非常高效地訪問。例如,在按字節(jié)尋址的機器中,2字節(jié)的short int型變量必須放在偶地址上,而4字節(jié)的long int型變量則必須存放在4的整數(shù)倍地址上。某些機器甚至根本就不能訪問沒有對齊的地址,因此必須要求所有的數(shù)據(jù)都正確地對齊。

六、什么叫做位域?

位域是指信息在存儲時,并不需要占用一個完整的字節(jié), 而只需占幾個或一個二進制位。例如在存放一個開關(guān)量時,只有0和1 兩種狀態(tài), 用一位二進位即可。為了節(jié)省存儲空間,并使處理簡便,C語言又提供了一種數(shù)據(jù)結(jié)構(gòu),稱為“位域”或“位段”。所謂“位域”是把一個字節(jié)中的二進位劃分為幾 個不同的區(qū)域, 并說明每個區(qū)域的位數(shù)。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾個不同的對象用一個字節(jié)的二進制位域來表示。

感謝各位的閱讀,以上就是“C++內(nèi)存對齊怎么理解”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對C++內(nèi)存對齊怎么理解這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI