1:gcc中支援但不推薦使用的指令
#pragma pack() :取消記憶體對齊訪問
#pragma pack(n) (n=1/2/4/8):按n位元組對齊 1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma pack(2)
struct
mystruct1
struct
mystruct2
#pragma pack()
以上這部分內容就是按2位元組對齊了。
分析:(1)#pragma是用來指揮編譯器,或者說設定編譯器的對齊方式的。編譯器的預設對齊方式是4,但是有時候我不希望對齊方式是4,而希望是別的(譬如希望1位元組對齊,也可能希望是8,甚至可能希望128位元組對齊)。
(2)常用的設定編譯器編譯器對齊命令有2種:第一種是#pragma pack(),這種就是設定編譯器1位元組對齊(有些人喜歡講:設定編譯器不對齊訪問,還有些講:取消編譯器對齊訪問);第二種是#pragma pack(4),這個括號中的數字就表示我們希望多少位元組對齊。
(3)我們需要#prgama pack(n)開頭,以#pragma pack()結尾,定義乙個區間,這個區間內的對齊引數就是n。
(4)#prgma pack的方式在很多c環境下都是支援的,但是gcc雖然也可以不過不建議使用。
2:gcc推薦的指令
__attribute__((packed)):取消記憶體對齊,或者說是1位元組對齊
__attribute__((aligned(n))):
設定結構體型別整體按n位元組對齊,注意是整體而不是這個結構體變數內的元素按n位元組對齊
12
3
4
5
6
struct
mystruct1
__attribute__((packed));
這樣這個結構體型別就按1位元組對齊,所以這個結構體型別佔7位元組 1
2
3
4
5
6
struct
mystruct2
__attribute__((aligned(2))) mystr2;
(不能是mystr2 __attribute__((aligned(2))) )
這樣mystruct2這個結構體型別就按2位元組對齊
(1)__attribute__((packed))使用時直接放在要進行記憶體對齊的型別定義的後面,然後它起作用的範圍只有加了這個東西的這乙個型別。
packed的作用就是取消對齊訪問。
(2)__attribute__((aligned(n)))使用時直接放在要進行記憶體對齊的型別定義的後面,然後它起作用的範圍只有加了這個東西的這乙個
型別(只能是加在型別後面,不能加在變數後面)
。它的作用是讓整個結構體變數整體進行n位元組對齊(注意是結構體變數整體n位元組對齊,而不是結構體內各元素也要n位元組對齊)
結構體對齊訪問還可以參考下面兩篇文章
C語言之結構體內存對齊
結構體的記憶體對齊 首先得掌握結構體對齊規則 1 第乙個成員在結構體變數偏移量為0的位址處。2 其他成員變數要對齊到某個數字 對齊數 的整數倍的位址處。對齊數 編譯器預設的乙個對齊數與該成員大小的較小值。vs中預設的值為8 linux中的預設值為4 3 結構體總大小為最大對齊數的整數倍。4 如果巢狀...
gcc 的記憶體對齊
cpu以位元組為單位編址,而c語言指標以指向的資料型別長度作自增和自減。gcc下的double的alignment requirement 在用編譯選項 malign double的時候,double的alignment requirement是雙字 32位機器上就是8 用 mno align do...
C語言 記憶體對齊
寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?講講位元組對齊吧.分割線 如果體系結構是不對齊的,a中的成員將會乙個挨乙個儲存,從而sizeof a 為11。顯然對齊更浪費了空間。那麼為什麼要使用對齊呢?體 繫結構...