pragma pack n 結構體對齊

2021-10-12 03:17:09 字數 1507 閱讀 7109

c語言**開發過程中,其實經常會遇到#pragma pack(n),#pragma pack(),#pragma pack(pack,n),#pragma pack(pop,n)等。並且這些語句一般出現在結構體前面。大家都知道這些是進行對齊的,但是關於是怎麼對齊的,總是理解不清晰。以下是我個人總結:

什麼是對齊?為什麼要對齊?

現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。

各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出,而如果存放在奇位址開始的地方,就可能會需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該int資料。顯然在讀取效率上下降很多。這也是空間和時間的博弈。

在c語言編譯器中提供了#pragma pack(n)來設定變數以n位元組對齊方式。n位元組對齊就是說變數存放的起始位址的偏移量有兩種情況:

第一:如果n大於等於該變數所占用的位元組數,那麼偏移量必須滿足預設的對齊方式;

第二:如果n小於該變數的型別所占用的位元組數,那麼偏移量為n的倍數,不用滿足預設的對齊方式。結構的總大小也有個約束條件,分下面兩種情況:如果n大於所有成員變數型別所占用的位元組數,那麼結構的總大小必須為占用空間最大的變數占用的空間數的倍數;否則必須為n的倍數。

#include #include #include typedef char int8;

typedef unsigned char uint8;

typedef short int16;

typedef unsigned short uint16;

typedef int int32;

typedef unsigned int uint32;

typedef long long int64;

typedef unsigned long long uint64;

#pragma pack(1)

typedef struct pack_modular_message_t;

#pragma pack(0)

typedef struct no_pack_modular_message_t;

int main()

編譯執行結果:

zhang@ubuntu140453200:/mnt/external/zhang/test/mzh$ ./struct_pragma_pack

pack struct size 62

no pack struct size 64

zhang@ubuntu140453200:/mnt/external/zhang/test/mzh$

pragma pack n 與記憶體對其問題

title pragma pack n 與記憶體對其問題 date 2016 06 08 15 32 11 categories c tags c c 記憶體對齊 pragma pack 作用 遮蔽掉編譯器為變數設定的預設的對其方式,設定自己的對其方式 而 pragma pack n 表示設定變數以...

rust對結構體排序

use std cmp ordering use rand rng 匯入外部的包.記得修改toml檔案 保證age是可比較的 pub struct person t std cmp partialord 注意泛型t的位置 impl t person t where t std cmp partial...

對結構體初始化

對結構體 struct a 有幾種初始化方式 struct a a1 或者struct a a1 或者struct a a1 核心喜歡用第一種,使用第一種和第二種時,成員初始化順序可變。轉一篇文章 在閱讀gnu linux核心 時,我們會遇到一種特殊的結構初始化方式。該方式是某些c教材 如譚二版 k...