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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

嵌入式C语言之struct内存分配分析

發(fā)布時(shí)間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 嵌入式C语言之struct内存分配分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文源于微信號《嵌入式ARM》。鏈接:http://mp.weixin.qq.com/s/j2mk6jY79nrJge2cDZVH_A


對結(jié)構(gòu)MyStruct采用sizeof會(huì)出現(xiàn)什么結(jié)果呢?sizeof(MyStruct)為多少呢?

?

也許你會(huì)這樣求:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

?但是當(dāng)在VC中測試上面結(jié)構(gòu)的大小時(shí),你會(huì)發(fā)現(xiàn)sizeof(MyStruct)=16。你知道為什么在VC中會(huì)得出這樣一個(gè)結(jié)果嗎?

?其實(shí),這是VC對變量存儲(chǔ)的一個(gè)特殊處理。為了提高CPU的存儲(chǔ)速度,VC對一些變量的起始地址做了對齊處理。

在默認(rèn)情況下,VC規(guī)定各成員變量存放的起始地址相對于結(jié)構(gòu)的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)的倍數(shù)。

下面列出常用類型的對齊方式(vs6.0&vs8.0,32位系統(tǒng))

?

?各成員變量在存放的時(shí)候根據(jù)在結(jié)構(gòu)中出現(xiàn)的順序依次申請空間,同時(shí)按照上面的對齊方式調(diào)整位置,空缺的字節(jié)VC會(huì)自動(dòng)填充。同時(shí)VC為了確保結(jié)構(gòu)的大小為結(jié)構(gòu)的字節(jié)邊界數(shù)(即該結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù))的倍數(shù),所以在為最后一個(gè)成員變量申請空間后,還會(huì)根據(jù)需要自動(dòng)填充空缺的字節(jié)。

?

下面用前面的例子來說明VC到底怎么樣來存放結(jié)構(gòu)的。

?

為上面的結(jié)構(gòu)分配空間的時(shí)候,VC根據(jù)成員變量出現(xiàn)的順序和對齊方式,依次分配。

?1)先為第一個(gè)成員dda1分配空間,其起始地址跟結(jié)構(gòu)的起始地址相同,剛好偏移量0剛好為sizeof(double)的倍數(shù),該成員變量占用zeof(double)=8個(gè)字節(jié);

?2)接下來為第二個(gè)成員dda分配空間,這時(shí)下一個(gè)可以分配的地址對于結(jié)構(gòu)的起始地址的偏移量為8,是sizeof(char)的倍數(shù),所以把dda存放在偏移量為8的地方滿足對齊方式,該成員變量占用sizeof(char)=1個(gè)字節(jié);

?3)接下來為第三個(gè)成員type分配空間,這時(shí)下一個(gè)可以分配的地址對于結(jié)構(gòu)的起始地址的偏移量為9,不是sizeof(int)=4的倍數(shù),為了滿足對齊方式對偏移量的約束問題,VC自動(dòng)填充3個(gè)字節(jié)(這三個(gè)字節(jié)沒有放什么東西),這時(shí)下一個(gè)可以分配的地址對于結(jié)構(gòu)的起始地址的偏移量為12,剛好是=4的倍數(shù),所以把type存放在偏移量為12的地方,該成員變量占用sizeof(int)=4個(gè)字節(jié);

?4)這時(shí)整個(gè)結(jié)構(gòu)的成員變量已經(jīng)都分配了空間,總的占用的空間大小為:

8+1+3+4=16,剛好為結(jié)構(gòu)的字節(jié)邊界數(shù)(即結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù)sizeof(double)=8)的倍數(shù),所以沒有空缺的字節(jié)需要填充。

?5)所以整個(gè)結(jié)構(gòu)的大小為:

sizeof(MyStruct)=8+1+3+4=16,其中有3個(gè)字節(jié)是VC自動(dòng)填充的,沒有放任何有意義的東西。

?

下面再舉個(gè)例子,交換一下上面的MyStruct的成員變量的位置,使它變成下面的情況:

?

?這個(gè)結(jié)構(gòu)占用的空間為多大呢?在VC6.0環(huán)境下,可以得到sizeof(MyStruct)=24。結(jié)合上面提到的分配空間的一些原則,分析下VC怎么樣為上面的結(jié)構(gòu)分配空間的。

?所有成員變量都分配了空間,空間總的大小為1+7+8+4=20,不是結(jié)構(gòu)的節(jié)邊界數(shù)(即結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù)sizeof(double)=8)的倍數(shù),所以需要填充4個(gè)字節(jié),以滿足結(jié)構(gòu)的大小為sizeof(double)=8的倍數(shù)。所以該結(jié)構(gòu)總的大小為:sizeof(MyStruct)1+7+8+4+4=24。其中總的有7+4=11個(gè)字節(jié)是VC自動(dòng)填充的,沒有放任何有意義的東西。

?

VC對結(jié)構(gòu)的存儲(chǔ)的特殊處理確實(shí)提高CPU存儲(chǔ)變量的速度,但是有時(shí)候也帶來了一些麻煩,我們也屏蔽掉變量默認(rèn)的對齊方式,自己可以設(shè)定變量的對齊方式。VC中提供了#pragma?pack(n)來設(shè)定變量以n字節(jié)對齊方式。n字節(jié)對齊就是說變量存放的起始地址的偏移量有兩種情況:第一、如果n大于等于該變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對齊方式,第二、如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對齊方式。結(jié)構(gòu)的總大小也有個(gè)約束條件,分下面兩種情況:如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);否則必須為n的倍數(shù)。

?下面舉例說明其用法:

?

?

以上結(jié)構(gòu)的大小為16,下面分析其存儲(chǔ)情況,首先為m1分配空間,其偏移量為0,滿足我們自己設(shè)定的對齊方式(4字節(jié)對齊),m1占用1個(gè)字節(jié)。接著開始為m4分配空間,這時(shí)其偏移量為1,需要補(bǔ)足3個(gè)字節(jié),這樣使偏移量滿足為n=4的倍數(shù)(因?yàn)?/span>sizeof(double)大于n,m4占用8個(gè)字節(jié)。接著為m3分配空間,這時(shí)其偏移量為12,滿足為4的倍數(shù),m3占用4個(gè)字節(jié)。這時(shí)已經(jīng)為所有成員變量分配了空間,共分配了16個(gè)字節(jié),滿足為n的倍數(shù)。如果把上面的#pragma?pack(4)改為#pragma?pack(16),那么我們可以得到結(jié)構(gòu)的大小為24

?VC6中,Project SettingsàC/C++àStruct member alignment中默認(rèn)值為8Bytes *Struct member alignment用以指定數(shù)據(jù)結(jié)構(gòu)中的成員變量在內(nèi)存中是按幾字節(jié)對齊的,根據(jù)計(jì)算機(jī)數(shù)據(jù)總線的位數(shù),不同的對齊方式存取數(shù)據(jù)的速度不一樣。這個(gè)參數(shù)對數(shù)據(jù)包網(wǎng)絡(luò)傳輸?shù)葢?yīng)用尤為重要,不是存取速度問題,而是數(shù)據(jù)位的精確定義問題,一般在程序中使用#pragma pack來指定。





總結(jié)之,即: (1)可以設(shè)置不同的對齊方式,設(shè)置方式如上面所述,一般系統(tǒng)默認(rèn)為8字節(jié)對齊。而我所知,嵌入式系統(tǒng)中一般默認(rèn)4字節(jié)對齊?(vs2015默認(rèn)4字節(jié)對齊) (2)VC中提供了#pragma?pack(n)來設(shè)定變量以n字節(jié)對齊方式。即在結(jié)構(gòu)體前后分別以#pragma?pack(n),#pragma?pack()進(jìn)行對齊設(shè)置。 n字節(jié)對齊就是說變量存放的起始地址的偏移量有兩種情況: 第一、如果n大于等于該變量類型所占用的字節(jié)數(shù),那么偏移量必須是該類型的整數(shù)倍。 第二、如果n小于該變量的類型所所占用的字節(jié)數(shù),那么偏移量必須是n的整數(shù)倍。
結(jié)構(gòu)的總大小也有個(gè)約束條件,分下面兩種情況: 如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);否則必須為n的倍數(shù)。

總結(jié)

以上是生活随笔為你收集整理的嵌入式C语言之struct内存分配分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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