C語言中字節(jié)對齊的幾種方式小結(jié)
前言
C語言調(diào)試筆記,C語言中字節(jié)對齊的幾種方式記錄一下
字節(jié)對齊是指數(shù)據(jù)存儲時(shí)按照一定的規(guī)則在內(nèi)存中排列,使得數(shù)據(jù)的訪問效率更高
一、自然對齊(默認(rèn)對齊方式)
1.原理:
自然對齊是編譯器默認(rèn)的對齊方式。在這種方式下,數(shù)據(jù)類型按照其自身的長度進(jìn)行對齊存儲。
例如,char類型(通常為 1 字節(jié))可以從任意地址開始存儲,因?yàn)樗拈L度就是 1 字節(jié);
short類型(通常為 2 字節(jié))的存儲地址是 2 的倍數(shù);
int類型(通常為 4 字節(jié))的存儲地址是 4 的倍數(shù);
double類型(通常為 8 字節(jié))的存儲地址是 8 的倍數(shù)等。
2.舉例:
#include <stdio.h>
struct NaturalAlignment {
char c; // 1字節(jié),地址可以是任意位置
int i; // 4字節(jié),會自動對齊到4的倍數(shù)地址
short s; // 2字節(jié),因?yàn)榍懊娴膇nt已經(jīng)是4字節(jié)對齊,所以這里也自然對齊
};
int main() {
struct NaturalAlignment na;
printf("Size of struct NaturalAlignment: %ld\n", sizeof(na));
// 輸出結(jié)果通常為1 + (3 padding) + 4 + 2 = 10字節(jié)
// 其中3字節(jié)是為了讓int能從4的倍數(shù)地址開始存儲而填充的字節(jié)
return 0;
}注意! 某些編譯器可能執(zhí)行結(jié)果是12,這跟32位和64位系統(tǒng)中機(jī)器字長有關(guān)。但是我們驗(yàn)證的是此種對齊方式
二、預(yù)處理指令
1.原理:
#pragma pack(n) 是一種預(yù)處理指令,用于指定結(jié)構(gòu)體或聯(lián)合體成員的對齊方式。
其中n表示對齊字節(jié)數(shù),編譯器會按照這個指定的字節(jié)數(shù)來對齊成員。
它會盡量按照不超過n字節(jié)的邊界來對齊成員,但如果成員本身長度大于n,則按照成員自身長度對齊
2.舉例
代碼如下(示例):
#include <stdio.h>
#pragma pack(1) // 指定按1字節(jié)對齊
struct PackedAlignment1 {
char c;
int i;
short s;
};
#pragma pack() // 恢復(fù)默認(rèn)對齊方式
#pragma pack(2) // 指定按2字節(jié)對齊
struct PackedAlignment2 {
char c;
int i;
short s;
};
#pragma pack() // 恢復(fù)默認(rèn)對齊方式
int main() {
struct PackedAlignment1 pa1;
struct PackedAlignment2 pa2;
printf("Size of struct PackedAlignment1: %ld\n", sizeof(pa1));
// 輸出結(jié)果為1 + 4 + 2 = 7字節(jié),因?yàn)榘?字節(jié)對齊,沒有填充字節(jié)
printf("Size of struct PackedAlignment2: %ld\n", sizeof(pa2));
// 輸出結(jié)果為1 + (1 padding) + 4 + 2 = 8字節(jié)
// 因?yàn)榘?字節(jié)對齊,char后填充1字節(jié)使int能從2的倍數(shù)地址開始存儲
return 0;
}三、編譯器一種屬性語法
1.原理
這是 GCC 編譯器提供的一種屬性語法,用于指定變量或類型的對齊字節(jié)數(shù)。
它主要用于對結(jié)構(gòu)體、聯(lián)合體或者變量強(qiáng)制指定對齊方式,n為對齊字節(jié)數(shù)。
當(dāng)用于結(jié)構(gòu)體時(shí),整個結(jié)構(gòu)體的大小會是n的倍數(shù)。
2.舉例
#include <stdio.h>
struct AlignedAttribute {
char c;
int i;
short s;
}__attribute__((aligned(4))); // 指定結(jié)構(gòu)體按4字節(jié)對齊
int main() {
struct AlignedAttribute aa;
printf("Size of struct AlignedAttribute: %ld\n", sizeof(aa));
// 輸出結(jié)果為4 + 4 + 4 = 12字節(jié)
// 因?yàn)榘?字節(jié)對齊,char后填充3字節(jié),short后填充2字節(jié)
// 使整個結(jié)構(gòu)體大小是4的倍數(shù)
return 0;
}總結(jié)
這些字節(jié)對齊方式在不同的場景下有不同的用途。在需要精確控制內(nèi)存布局或者與硬件設(shè)備進(jìn)行數(shù)據(jù)交互時(shí),合理的字節(jié)對齊方式可以確保數(shù)據(jù)的正確讀寫和高效傳輸
到此這篇關(guān)于C語言中字節(jié)對齊的幾種方式小結(jié)的文章就介紹到這了,更多相關(guān)C語言 字節(jié)對齊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VScode搭建OpenCV環(huán)境的詳細(xì)步驟
用vscode來寫opencv代碼需要自己編譯OpenCV,主要用到MinGW-w64和CMake工具。接下來通過本文給大家介紹VScode搭建OpenCV環(huán)境的相關(guān)知識,需要的朋友可以參考下2021-11-11
c++將vector迭代器轉(zhuǎn)換為指針的實(shí)現(xiàn)方式
這篇文章主要介紹了c++將vector迭代器轉(zhuǎn)換為指針的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11

