C語言中結(jié)構(gòu)體、聯(lián)合體的成員內(nèi)存對(duì)齊情況
前言
最近項(xiàng)目進(jìn)行中,遇到一個(gè)小問題,在數(shù)據(jù)協(xié)議傳輸過程中,我為了方便解析,就定義了一個(gè)結(jié)構(gòu)體,在數(shù)據(jù)的指針傳入函數(shù)的時(shí)候,我用定義好的結(jié)構(gòu)體進(jìn)行強(qiáng)制轉(zhuǎn)化,沒想到一直解析失敗,調(diào)試很久,終于反應(yīng)過來,在用結(jié)構(gòu)體指針對(duì)數(shù)據(jù)強(qiáng)制轉(zhuǎn)換時(shí),定義結(jié)構(gòu)體我沒有注意到數(shù)據(jù)對(duì)齊,因?yàn)樵诘讓訉?shí)現(xiàn)中,我傳入的數(shù)據(jù)buffer是排列整齊的,而強(qiáng)制轉(zhuǎn)化的結(jié)構(gòu)體格式中,我定義的時(shí)候沒有使用__attribute__((__packed__))或者_(dá)_packed強(qiáng)制數(shù)據(jù)對(duì)齊,導(dǎo)致結(jié)構(gòu)體成員真實(shí)排列會(huì)按照成員中最大的變量的格式進(jìn)行對(duì)其,缺少的地方被虛擬補(bǔ)充位置。
下面就稍微簡(jiǎn)單描述一下結(jié)構(gòu)體數(shù)據(jù)對(duì)齊的講解:
圖片描述的兩種實(shí)現(xiàn)結(jié)構(gòu)對(duì)齊的聲明,適用于結(jié)構(gòu)體和聯(lián)合的聲明。

接下來展示幾組聲明結(jié)構(gòu)體后成員變量對(duì)齊的方式:
/*第一個(gè)示例*/
struct stc
{
char one;
short two;
char three;
int four;
} c,d;
int main (void)
{
c.one=1;
return 0;
}
第一個(gè)示例代碼配合下方內(nèi)存排列的圖片,可以看到,在正常無特殊聲明的情況下,結(jié)構(gòu)體在內(nèi)存排列是按照結(jié)構(gòu)體成員中最大的變量的大小進(jìn)行排列的。
第一處示例代碼中,最大的成員變量是int型,一個(gè)int型在我使用的32位ARM環(huán)境中占4個(gè)byte,所以在排列中,最小的排列單位是4byte,而其他類型,char占1個(gè)byte,short占2個(gè)byte,在排列的第一行的4個(gè)byte中,一個(gè)char+一個(gè)short類型為3byte,所以需要補(bǔ)上1byte的虛擬空間,第二行的4byte中,還剩下一個(gè)char和int,int單獨(dú)占一行,所以char需要補(bǔ)上3byte才能排列整齊。
/*第二個(gè)示例*/
struct __attribute__((packed)) stc
{
char one;
short two;
char three;
int four;
} c,d;
int main (void)
{
c.one=1;
return 0;
}
第二個(gè)示例代碼配合下方內(nèi)存排列的圖片,可以看到,代碼使用了__attribute__((packed))聲明,這個(gè)聲明的含義是,令相關(guān)的結(jié)構(gòu)體與聯(lián)合體強(qiáng)制一字節(jié)對(duì)齊。所以在內(nèi)存中排列中,按照1byte的數(shù)據(jù)對(duì)齊方式,成員變量緊密排布。

/*第三個(gè)示例*/
#pragma pack (2)
struct stc
{
char one;
short two;
char three;
int four;
} c,d;
int main (void)
{
c.one=1;
return 0;
}
/*第四個(gè)示例*/
#pragma pack (4)
struct stc
{
char one;
short two;
char three;
int four;
} c,d;
int main (void)
{
c.one=1;
return 0;
}
第三、四個(gè)示例代碼配合下方內(nèi)存排列的圖片,可以看到,代碼使用了#pragma pack (n)聲明,這個(gè)聲明的含義是,令相關(guān)的結(jié)構(gòu)體與聯(lián)合體強(qiáng)制N字節(jié)對(duì)齊,這個(gè)聲明和__attribute__((packed))功能類似,但是__attribute__((packed))只能進(jìn)行一字節(jié)強(qiáng)制對(duì)齊,而#pragma pack (n)對(duì)齊字節(jié)數(shù),由n進(jìn)行控制,所以有很多的靈活性。具體使用可以從下圖成員對(duì)齊情況了解,此處就不進(jìn)行贅述了。

總結(jié)
到此這篇關(guān)于C語言中結(jié)構(gòu)體、聯(lián)合體的成員內(nèi)存對(duì)齊情況的文章就介紹到這了,更多相關(guān)C語言結(jié)構(gòu)體、聯(lián)合體內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則講解
- C語言詳解結(jié)構(gòu)體的內(nèi)存對(duì)齊與大小計(jì)算
- C語言詳解熱門考點(diǎn)結(jié)構(gòu)體內(nèi)存對(duì)齊
- C語言 詳細(xì)分析結(jié)構(gòu)體的內(nèi)存對(duì)齊
- C語言結(jié)構(gòu)體中內(nèi)存對(duì)齊的問題理解
- C語言結(jié)構(gòu)體內(nèi)存對(duì)齊詳解
- C語言熱門考點(diǎn)結(jié)構(gòu)體與內(nèi)存對(duì)齊詳解
- C語言中結(jié)構(gòu)體與內(nèi)存對(duì)齊實(shí)例解析
- C語言詳細(xì)分析結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則
相關(guān)文章
C++ 數(shù)據(jù)結(jié)構(gòu)之布隆過濾器
這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu)之布隆過濾器的相關(guān)資料,需要的朋友可以參考下2017-06-06
C++定義和初始化string對(duì)象實(shí)例詳解
這篇文章主要為大家介紹了C++定義和初始化string對(duì)象實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12

