最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

關(guān)于C語(yǔ)言中Malloc()內(nèi)存對(duì)齊

2021-06-01 14:48 作者:陳偉國(guó)AE  | 我要投稿

眾所周知,在C語(yǔ)言中可以通過(guò)malloc()函數(shù)在堆區(qū)創(chuàng)建一塊動(dòng)態(tài)內(nèi)存空間,例如:

malloc(1);? //在堆區(qū)創(chuàng)建1個(gè)字節(jié)大小的空間

但是實(shí)際情況下malloc()創(chuàng)建的數(shù)據(jù)大小遠(yuǎn)超過(guò)1字節(jié),為什么會(huì)導(dǎo)致這個(gè)問(wèn)題呢,這就有關(guān)內(nèi)存對(duì)齊問(wèn)題了。

1.實(shí)驗(yàn)

我分別在Win10 64下和Stm32下運(yùn)行了如下代碼,并得到結(jié)果:

PC運(yùn)行結(jié)果
Stm32運(yùn)行結(jié)果

先觀察運(yùn)行結(jié)果,Stm32分別輸出了8和16,明明我們分配的是malloc(1),應(yīng)該輸出1字節(jié)才對(duì)啊,怎么會(huì)變成8,更不要用說(shuō)16了。

這就要引入內(nèi)存對(duì)齊malloc堆塊結(jié)構(gòu)的的問(wèn)題了。

首先我們先看malloc()堆塊結(jié)構(gòu),malloc()函數(shù)申請(qǐng)的堆塊是由兩部分組成:Header和數(shù)據(jù)區(qū)

malloc分配的堆塊結(jié)構(gòu)

malloc()函數(shù)創(chuàng)建的堆空間由兩部分組成:Header和數(shù)據(jù),這就意味著malloc()真實(shí)分配的空間大小是Header大小+數(shù)據(jù)大小。

以下代碼為malloc()堆塊Header結(jié)構(gòu):

typedef?long?Align;

union?header {

????struct?{

????????union?header *ptr;

????????unsigned?

????} s;

????Align x;

};

可以看到Header是共同體Union,共同體所有元素共享一塊內(nèi)存空間,共同體所占用的空間大小是共同體中最大的元素的大小,也就是long Align x,眾所周知long在64位機(jī)子占用8字節(jié),在32位機(jī)子占用4字節(jié)。

Header長(zhǎng)度是4字節(jié)或8字節(jié)(根據(jù)機(jī)器字長(zhǎng)決定)


注意:我經(jīng)過(guò)Stm32平臺(tái)和Win10平臺(tái)實(shí)驗(yàn)論證,Header區(qū)和數(shù)據(jù)區(qū)是一個(gè)整體,計(jì)算實(shí)際內(nèi)存占用時(shí)先把數(shù)據(jù)區(qū)和Header長(zhǎng)度相加,然后把相加后的結(jié)果作內(nèi)存對(duì)齊。以32位機(jī)子的malloc(1)為例,把數(shù)據(jù)區(qū)1字節(jié)加上Header的4字節(jié)得到總共5字節(jié),再整體作內(nèi)存對(duì)齊得到8字節(jié),實(shí)際內(nèi)存占用為8字節(jié)。


再說(shuō)內(nèi)存對(duì)齊問(wèn)題

比如此處我用Stm32申請(qǐng)了1個(gè)字節(jié)的堆空間,實(shí)際上他卻分配了8個(gè)字節(jié)給我,按照malloc()函數(shù)分配的堆塊結(jié)構(gòu),應(yīng)該是1個(gè)字節(jié)的數(shù)據(jù)區(qū)+4個(gè)字節(jié)的Header區(qū),再經(jīng)過(guò)內(nèi)存對(duì)齊,小于8字節(jié)的區(qū)域擴(kuò)展到8字節(jié)存儲(chǔ),進(jìn)行內(nèi)存對(duì)齊后我們總共占用8字節(jié)。

經(jīng)過(guò)測(cè)試,在不同的編譯環(huán)境和平臺(tái)下,系統(tǒng)默認(rèn)的內(nèi)存對(duì)齊系數(shù)是不一致的,32位數(shù)系統(tǒng)是8字節(jié)(少于8字節(jié)則以8字節(jié)存儲(chǔ),大于8字節(jié)則擴(kuò)展8字節(jié)存儲(chǔ)),64位系統(tǒng)是16字節(jié)(少于16字節(jié)則以16字節(jié)存儲(chǔ),大于16字節(jié)則擴(kuò)展16字節(jié)存儲(chǔ))

Stm32經(jīng)過(guò)測(cè)試,對(duì)齊系數(shù)是8字節(jié),但是注意,經(jīng)過(guò)我的實(shí)驗(yàn),在Header區(qū)4字節(jié)加上數(shù)據(jù)區(qū)大小不產(chǎn)生溢出時(shí)(兩者相加不超過(guò)最近的8的倍數(shù)),對(duì)齊系數(shù)會(huì)在8字節(jié)和16字節(jié)間交替,產(chǎn)生溢出時(shí)就是正常的8字節(jié)對(duì)齊,這就是為什么上面測(cè)試會(huì)出現(xiàn)8和16交替的情況。當(dāng)malloc()申請(qǐng)1字節(jié)時(shí),數(shù)據(jù)區(qū)長(zhǎng)度1字節(jié)加上Header區(qū)長(zhǎng)度4字節(jié)經(jīng)過(guò)內(nèi)存對(duì)齊后變成8字節(jié),總長(zhǎng)度=(數(shù)據(jù)區(qū)1字節(jié)+Header區(qū)4字節(jié))->內(nèi)存對(duì)齊=8字節(jié)

經(jīng)過(guò)實(shí)驗(yàn),Stm32F103C8的內(nèi)存對(duì)齊系數(shù)是8字節(jié)和16字節(jié)交替的,當(dāng)數(shù)據(jù)區(qū)長(zhǎng)度加Header長(zhǎng)度產(chǎn)生溢出時(shí),內(nèi)存對(duì)齊系數(shù)就是正常的8字節(jié),當(dāng)數(shù)據(jù)區(qū)長(zhǎng)度加Header長(zhǎng)度不產(chǎn)生溢出時(shí),內(nèi)存對(duì)齊系數(shù)就會(huì)交替。例如malloc(1),數(shù)據(jù)區(qū)長(zhǎng)度是1字節(jié),加上4后小于8不產(chǎn)生溢出,則內(nèi)存對(duì)齊系數(shù)就會(huì)在8和16之間交替,再例如malloc(7),7+4大于8產(chǎn)生溢出,那么內(nèi)存對(duì)齊系數(shù)就是8字節(jié),總占用16字節(jié)。使用時(shí)需注意,這也就解釋了為什么上面示例中一會(huì)輸出8字節(jié)一會(huì)輸出16字節(jié)了

Win10 64經(jīng)過(guò)測(cè)試,對(duì)齊系數(shù)是16字節(jié),當(dāng)malloc()申請(qǐng)32字節(jié)時(shí),實(shí)際我們需要的是32字節(jié)數(shù)據(jù)區(qū)空間+8字節(jié)Header空間,也就是40字節(jié),數(shù)據(jù)區(qū)和Header區(qū)相加后內(nèi)存對(duì)齊,系統(tǒng)會(huì)分配48字節(jié)的空間給我們存儲(chǔ),如下圖:

WIn10測(cè)試


系統(tǒng)最小malloc()分配空間大小

在64位系統(tǒng),如果申請(qǐng)內(nèi)存為1~24字節(jié),系統(tǒng)內(nèi)存消耗32字節(jié),當(dāng)申請(qǐng)25字節(jié)的內(nèi)存時(shí),系統(tǒng)內(nèi)存消耗48字節(jié)。而對(duì)于32位系統(tǒng),申請(qǐng)內(nèi)存為1~12字節(jié)時(shí),系統(tǒng)內(nèi)存消耗為16字節(jié),當(dāng)申請(qǐng)內(nèi)存為13字節(jié)時(shí),系統(tǒng)內(nèi)存消耗為24字節(jié)


總結(jié)

malloc()函數(shù)創(chuàng)建的實(shí)際空間大小=系統(tǒng)最小分配空間大小+超出部分內(nèi)存對(duì)齊后的值

注意:下例Stm32內(nèi)存對(duì)齊系數(shù)以8字節(jié)為準(zhǔn)

例如:

malloc(1)

在Win10 64下實(shí)際創(chuàng)建(1+8)=系統(tǒng)最小分配空間32+超出部分0=32字節(jié)

在Stm32下實(shí)際創(chuàng)建(1+8)=系統(tǒng)最小分配空間8+(超出部分1->內(nèi)存對(duì)齊后8)=16字節(jié)

再例如:

malloc(32)

在Win10?64下實(shí)際創(chuàng)建(32+8)=系統(tǒng)最小分配空間32+(超出部分8->內(nèi)存對(duì)齊后16)=48字節(jié)

在Stm32下實(shí)際創(chuàng)建(32+8)=系統(tǒng)最小分配空間8+(超出部分32->內(nèi)存對(duì)齊后32)=40字節(jié)

再例如:

malloc(47)

在Win10?64下實(shí)際創(chuàng)建(47+8)=系統(tǒng)最小分配空間32+(超出部分23->內(nèi)存對(duì)齊后32)=64字節(jié)

在Stm32下實(shí)際創(chuàng)建(47+8)=系統(tǒng)最小分配空間8+(超出部分47->內(nèi)存對(duì)齊后48)=56字節(jié)


Win10 64 malloc(47)測(cè)試
Stm32 malloc(47)測(cè)試

相信很多帶佬不用看我上面的廢話,直接看例子就能看懂了。




關(guān)于C語(yǔ)言中Malloc()內(nèi)存對(duì)齊的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
洪洞县| 宾川县| 孟州市| 于都县| 旬阳县| 日土县| 托克逊县| 萝北县| 定州市| 保德县| 黔江区| 灵川县| 白银市| 绥阳县| 荔波县| 海安县| 丹巴县| 宁明县| 望城县| 武夷山市| 通渭县| 高安市| 巢湖市| 海盐县| 锡林浩特市| 霞浦县| 宝丰县| SHOW| 北碚区| 稻城县| 舒兰市| 巴彦淖尔市| 孟州市| 平邑县| 辰溪县| 波密县| 老河口市| 五寨县| 南昌市| 沭阳县| 依兰县|