日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

四字节内存对齐

發(fā)布時(shí)間:2025/6/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 四字节内存对齐 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先我們先看看下面的C語(yǔ)言的結(jié)構(gòu)體:

[cpp]?view plain?copy
  • typedef?struct?MemAlign??
  • {??
  • ????int?a;??
  • ????char?b[3];??
  • ????int?c;??
  • }MemAlign;??
  • ????以上這個(gè)結(jié)構(gòu)體占用內(nèi)存多少空間呢?也許你會(huì)說(shuō),這個(gè)簡(jiǎn)單,計(jì)算每個(gè)類(lèi)型的大小,將它們相加就行了,以32為平臺(tái)為例,int類(lèi)型占4節(jié),char占用1節(jié),所以:4 + 3 + 4 = 11,那么這個(gè)結(jié)構(gòu)體一共占用11節(jié)空間。好吧,那么我們就用實(shí)踐來(lái)證明是否正確,我們用sizeof運(yùn)算符來(lái)求出這個(gè)結(jié)構(gòu)體占用內(nèi)存空間大小,sizeof(MemAlign),出乎意料的是,結(jié)果居然為12?看來(lái)我們錯(cuò)了?當(dāng)然不是,而是這個(gè)結(jié)構(gòu)體被優(yōu)化了,這個(gè)優(yōu)化有個(gè)另外一個(gè)名叫“對(duì)齊”,那么這個(gè)對(duì)齊到底做了什么樣的優(yōu)化呢,聽(tīng)我慢慢解釋,再解釋之前我們先看一個(gè)圖,圖如下:

    ????相信學(xué)過(guò)匯編的朋友都很熟悉這張圖,這張圖就是CPU與內(nèi)存如何進(jìn)行數(shù)據(jù)交換的模型,其中,左邊藍(lán)色的方框是CPU,右邊綠色的方框是內(nèi)存,內(nèi)存上面的0~3是內(nèi)存地址。這里我們這張圖是以32位CPU作為代表,我們都知道,32位CPU是以雙字(DWORD)為單位進(jìn)行數(shù)據(jù)傳輸?shù)?#xff0c;也正因?yàn)檫@點(diǎn),造成了另外一個(gè)問(wèn)題,那么這個(gè)問(wèn)題是什么呢?這個(gè)問(wèn)題就是,既然32位CPU以雙字進(jìn)行數(shù)據(jù)傳輸,那么,如果我們的數(shù)據(jù)只有8位或16位數(shù)據(jù)的時(shí)候,是不是CPU就按照我們數(shù)據(jù)的位數(shù)來(lái)進(jìn)行數(shù)據(jù)傳輸呢?其答案是否定的,如果這樣會(huì)使得CPU硬件變的更復(fù)雜,所以32位CPU傳輸數(shù)據(jù)無(wú)論是8位或16位都是以雙字進(jìn)行數(shù)據(jù)傳輸。那么也罷,8位或16位一樣可以傳輸,但是,事情并非像我們想象的那么簡(jiǎn)單,比如,一個(gè)int類(lèi)型4節(jié)的數(shù)據(jù)如果放在上圖內(nèi)存地址1開(kāi)始的位置,那么這個(gè)數(shù)據(jù)占用的內(nèi)存地址為1~4,那么這個(gè)數(shù)據(jù)就被分為了2個(gè)部分,一個(gè)部分在地址0~3中,另外一部分在地址4~7中,又由于32位CPU以雙字進(jìn)行傳輸,所以,CPU會(huì)分2次進(jìn)行讀取,一次先讀取地址0~3中內(nèi)容,再一次讀取地址4~7中數(shù)據(jù),最后CPU提取并組合出正確的int類(lèi)型數(shù)據(jù),舍棄掉無(wú)關(guān)數(shù)據(jù)。那么反過(guò)來(lái),如果我們把這個(gè)int類(lèi)型4節(jié)的數(shù)據(jù)放在上圖從地址0開(kāi)始的位置會(huì)怎樣呢?讀到這里,也許你明白了,CPU只要進(jìn)行一次讀取就可以得到這個(gè)int類(lèi)型數(shù)據(jù)了。沒(méi)錯(cuò),就是這樣,這次CPU只用了一個(gè)周期就得到了數(shù)據(jù),由此可見(jiàn),對(duì)內(nèi)存數(shù)據(jù)的擺放是多么重要啊,擺放正確位置可以減少CPU的使用資源。

    那么,內(nèi)存對(duì)齊有哪些原則呢?我總結(jié)了一下大致分為三條:
    第一條:第一個(gè)成員的首地址為0
    第二條:每個(gè)成員的首地址是自身大小的整數(shù)倍
    ???????第二條補(bǔ)充:以4節(jié)對(duì)齊為例,如果自身大小大于4節(jié),都以4節(jié)整數(shù)倍為基準(zhǔn)對(duì)齊。
    第三條:最后以結(jié)構(gòu)總體對(duì)齊。
    ????????第三條補(bǔ)充:以4節(jié)對(duì)齊為例,取結(jié)構(gòu)體中最大成員類(lèi)型倍數(shù),如果超過(guò)4節(jié),都以4節(jié)整數(shù)倍為基準(zhǔn)對(duì)齊。(其中這一條還有個(gè)名叫:“補(bǔ)齊”,補(bǔ)齊的目的就是多個(gè)結(jié)構(gòu)變量挨著擺放的時(shí)候也滿(mǎn)足對(duì)齊的要求。)

    ????上述的三原則聽(tīng)起來(lái)還是比較抽象,那么接下來(lái)我們通過(guò)一個(gè)例子來(lái)加深對(duì)內(nèi)存對(duì)齊概念的理解,下面是一個(gè)結(jié)構(gòu)體,我們動(dòng)手算出下面結(jié)構(gòu)體一共占用多少內(nèi)存?假設(shè)我們以32位平臺(tái)并且以4節(jié)對(duì)齊方式:

    [cpp]?view plain?copy
  • #pragma?pack(4)??
  • typedef?struct?MemAlign??
  • {??
  • ????char?a[18];??
  • ????double?b;?????
  • ????char?c;??
  • ????int?d;????
  • ????short?e;??????
  • }MemAlign;??
  • 下圖為對(duì)齊后結(jié)構(gòu)如下:

    我們就以這個(gè)圖來(lái)講解是如何對(duì)齊的:
    第一個(gè)成員(char a[18]):首先,假設(shè)我們把它放到內(nèi)存開(kāi)始地址為0的位置,由于第一個(gè)成員占18個(gè)節(jié),所以第一個(gè)成員占用內(nèi)存地址范圍為0~18。
    第二個(gè)成員(double b):由于double類(lèi)型占8節(jié),又因?yàn)?節(jié)大于4節(jié),所以就以4節(jié)對(duì)齊為基準(zhǔn)。由于第一個(gè)成員結(jié)束地址為18,那么地址18并不是4的整數(shù)倍,我們需要再加2個(gè)節(jié),也就是從地址20開(kāi)始擺放第二個(gè)成員。
    第三個(gè)成員(char c):由于char類(lèi)型占1節(jié),任意地址是1節(jié)的整數(shù)倍,所以我們就直接將其擺放到緊接第二個(gè)成員之后即可。
    個(gè)成員(int d):由于int類(lèi)型占4節(jié),但是地址29并不是4的整數(shù)倍,所以我們需要再加3個(gè)節(jié),也就是從地址32開(kāi)始擺放這個(gè)成員。
    第五個(gè)成員(short e):由于short類(lèi)型占2節(jié),地址36正好是2的整數(shù)倍,這樣我們就可以直接擺放,無(wú)需填充節(jié),緊跟其后即可。
    ????這樣我們內(nèi)存對(duì)齊就完成了。但是離成功還差那么一步,那是什么呢?對(duì),是對(duì)整個(gè)結(jié)構(gòu)體補(bǔ)齊,接下來(lái)我們就補(bǔ)齊整個(gè)結(jié)構(gòu)體。那么,先讓我們回顧一下補(bǔ)齊的原則:“以4節(jié)對(duì)齊為例,取結(jié)構(gòu)體中最大成員類(lèi)型倍數(shù),如果超過(guò)4節(jié),都以4節(jié)整數(shù)倍為基準(zhǔn)對(duì)齊。”在這個(gè)結(jié)構(gòu)體中最大類(lèi)型為double類(lèi)型(占8節(jié)),又由于8節(jié)大于4?節(jié),所以我們還是以4節(jié)補(bǔ)齊為基準(zhǔn),整個(gè)結(jié)構(gòu)體結(jié)束地址為38,而地址38并不是4的整數(shù)倍,所以我們還需要加額外2個(gè)節(jié)來(lái)填充結(jié)構(gòu)體,如下圖紅色的就是補(bǔ)齊出來(lái)的空間:

    到此為止,我們內(nèi)存對(duì)齊與補(bǔ)齊就完畢了!接下來(lái)我們用實(shí)驗(yàn)來(lái)證明真理,程序如下:

    [cpp]?view plain?copy
  • #include?<stdio.h>??
  • #include?<memory.h>??
  • ??
  • //?由于VS2010默認(rèn)是8<strong?style="BACKGROUND-COLOR:?#ffff66;?COLOR:?black">字</strong>節(jié)對(duì)齊,我們??
  • //?通過(guò)預(yù)編譯來(lái)通知編譯器我們以4<strong?style="BACKGROUND-COLOR:?#ffff66;?COLOR:?black">字</strong>節(jié)對(duì)齊??
  • #pragma?pack(4)??
  • ??
  • //?用于測(cè)試的結(jié)構(gòu)體??
  • typedef?struct?MemAlign??
  • {??
  • ????char?a[18];?//?18?bytes??
  • ????double?b;???//?08?bytes???
  • ????char?c;?????//?01?bytes??
  • ????int?d;??????//?04?bytes??
  • ????short?e;????//?02?bytes??
  • }MemAlign;??
  • ??
  • int?main()??
  • {??
  • ????//?定義一個(gè)結(jié)構(gòu)體變量??
  • ????MemAlign?m;??
  • ????//?定義個(gè)以指向結(jié)構(gòu)體指針??
  • ????MemAlign?*p?=?&m;??
  • ????//?依次對(duì)各個(gè)成員進(jìn)行填充,這樣我們可以??
  • ????//?動(dòng)態(tài)觀察內(nèi)存變化情況??
  • ????memset(?&m.a,?0x11,?sizeof(m.a)?);??
  • ????memset(?&m.b,?0x22,?sizeof(m.b)?);??
  • ????memset(?&m.c,?0x33,?sizeof(m.c)?);??
  • ????memset(?&m.d,?0x44,?sizeof(m.d)?);??
  • ????memset(?&m.e,?0x55,?sizeof(m.e)?);??
  • ????//?由于有補(bǔ)齊原因,所以我們需要對(duì)整個(gè)??
  • ????//?結(jié)構(gòu)體進(jìn)行填充,補(bǔ)齊對(duì)齊剩下的<strong?style="BACKGROUND-COLOR:?#ffff66;?COLOR:?black">字</strong>節(jié)??
  • ????//?以便我們可以觀察到變化??
  • ????memset(?&m,?0x66,?sizeof(m)?);??
  • ????//?輸出結(jié)構(gòu)體大小??
  • ????printf(?"sizeof(MemAlign)?=?%d",?sizeof(m)?);??
  • }??
  • 程序運(yùn)行過(guò)程中,查看內(nèi)存如下:

    其中,各種顏色帶下劃線(xiàn)的代表各個(gè)成員變量,藍(lán)色方框的代表為內(nèi)存對(duì)齊時(shí)候填補(bǔ)的多余節(jié),由于這里看不到補(bǔ)齊效果,我們接下來(lái)看下圖,下圖籃框包圍的節(jié)就是與上圖的交集以外的部分就是補(bǔ)齊所填充的節(jié)。

    在最后,我在談一談關(guān)于補(bǔ)齊的作用,補(bǔ)齊其實(shí)就是為了讓這個(gè)結(jié)構(gòu)體定義的數(shù)組變量時(shí)候,數(shù)組內(nèi)部,也同樣滿(mǎn)足內(nèi)存對(duì)齊的要求,為了更好的理解這點(diǎn),我做了一個(gè)跟本例子相對(duì)照的圖:






    總結(jié)

    以上是生活随笔為你收集整理的四字节内存对齐的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久亚洲一区二区 | 色一区二区| av自拍网| jizz黄色片 | 日韩欧美专区 | 人人爽人人爽人人爽人人爽 | 在线观看视频亚洲 | 国内精品久久久 | 免费午夜人成电影 | 色婷婷婷婷色 | 亚洲精品成人影视 | 求av网站| 午夜av免费看| 日韩欧美一区二区三区四区 | 人人妻人人澡人人爽 | 欧美偷拍一区二区 | 多啪啪免费视频 | 日本一区二区免费视频 | 亚洲国产精品第一页 | www.伊人久久| 无码精品国产一区二区三区 | 成人激情小说网站 | 91亚洲精品久久久蜜桃借种 | 51av视频 | 五月天亚洲综合 | 女人的av| 仙踪林久久久久久久999 | 国产精品无码久久久久久电影 | 日韩久久视频 | 色综合激情网 | 无码少妇一级AV片在线观看 | 欧美特级a| 男女洗澡互摸私密部位视频 | 亚洲一区二区三区在线播放 | 无码人妻精品一区二区中文 | 嫩草网站 | 日韩黄色av | www.性欧美| 曰韩在线 | 亚洲电影影音先锋 | 国产影视av | 久久久久久久网 | 欧美日韩一区二区视频在线观看 | 中文字幕乱码一二三区 | 老师的肉丝玉足夹茎 | xxxxxxxx黄色片 | 欧美一区二区黄片 | 天天躁夜夜躁狠狠躁 | 婷婷五月在线视频 | 91黄在线观看| 国产精品免费看 | av免费网 | 女优一区二区三区 | 欧美激情黄色 | 国产午夜激情视频 | 国产成人综合在线 | 精品一区二区三区免费看 | 日日日插插插 | 两个人做羞羞的视频 | 亚欧在线视频 | 精品产国自在拍 | 中文字幕黄色片 | 国产精品视频一区在线观看 | 在线不卡av电影 | 欧美大片一区二区三区 | 香蕉狠狠爱视频 | 午夜久久网站 | 香蕉视频97 | 视色影院 | 国产肥老妇视频 | av最新资源| 中文字幕免费高清在线观看 | 最近中文字幕在线中文视频 | 天天躁日日躁狠狠躁免费麻豆 | 国产又黄又猛的视频 | 免费观看的黄色网址 | 免费一区二区视频 | 欧美黄色影院 | 中国一级片黄色一级片黄 | 久久这里只有精品首页 | 91极品视觉盛宴 | 亚洲小说区图片区都市 | 黑丝袜av | 欧美11一13sex性hd | 午夜视频在线免费观看 | 日韩va在线观看 | 99re6在线视频 | 午夜tv | 五月天激情综合网 | 亚洲h网站| 精品久久久久久久久久久久久久久久 | 日产精品久久久久久久 | 久久精品无码一区二区三区免费 | 免费国产在线观看 | 二级黄色大片 | 91抖音在线观看 | 欧美日韩视频免费 | 色婷婷777777仙踪林 | 欧美另类日韩 |