c11 的對齊特性比用位填充位元組更自然,它們還代表了c在處理硬體相關問題上的能力。
在這種上下文中,對齊指的是如何安排物件在記憶體中的位置。
例如,為了效率最大化,系統可能要把乙個 double 型別的值儲存在4 字 節記憶體位址上,但卻允許把char儲存在任意位址。大部分程式設計師都對對齊不 以為然。但是,有些情況又受益於對齊控制。例如,把資料從乙個硬體位置 轉移到另乙個位置,或者呼叫指令同時操作多個資料項。
_alignof運算子給出乙個型別的對齊要求,在關鍵字_alignof後面的圓括 號中寫上型別名即可:
size_t d_align =
_alignof
(float
);
假設d_align的值是4,意思是float型別物件的對齊要求是4。也就是說,4是儲存該型別值相鄰位址的位元組數。一般而言,對齊值都應該是2的非負整數次冪。較大的對齊值被稱為stricter或stronger,較小的對齊值被稱為 weaker。
可以使用_alignas 說明符指定乙個變數或型別的對齊值。但是,不應該要求該值小於基本對齊值。例如,如果float型別的對齊要求是4,不要請求其對齊值是1或2。該說明符用作宣告的一部分,說明符後面的圓括號內包含 對齊值或型別:
_alignas
(double
)char c1;
_alignas(8
)char c2;
unsigned
char
_alignas
(long
double
) c_arr[
sizeof
(long
double)]
;
// align.c -- 使用 _alignof 和 _alignas (c11)
#include
intmain
(void
)該程式的輸出如下:
char alignment:
1double alignment:
8&dx:
0x7fff5fbff660
&ca:
0x7fff5fbff65f
&cx:
0x7fff5fbff65e
&dz:
0x7fff5fbff650
&cb:
0x7fff5fbff64f
&cz:
0x7fff5fbff648
在我們的系統中,double的對齊值是8,這意味著位址的型別對齊可以 被8整除。以0或8結尾的十六進製制位址可被8整除。這就是位址常用兩個 double型別的變數和char型別的變數cz(該變數是double對齊值)。因為char 的對齊值是1,對於普通的char型別變數,編譯器可以使用任何位址。
在程式中包含 stdalign.h 標頭檔案後,就可以把 alignas 和 alignof 分別作為 _alignas 和_alignof的別名。這樣做可以與c++關鍵字匹配。
1184
c11在stdlib.h庫還新增了乙個新的記憶體分配函式,用於對齊動態分配的 記憶體。該函式的原型如下:
void
*aligned_alloc
(size_t alignment, size_t size)
;
第1個引數代表指定的對齊,第2個引數是所需的位元組數,其值應是第1 個引數的倍數。與其他記憶體分配函式一樣,要使用free()函式釋放之前分配 的記憶體。 C C 位元組對齊問題
位元組對齊的原因 為了提高 cpu 的儲存速度,編譯器會對 struct 和 union的儲存進行優化,即進行位元組對齊。對齊方式 對於 struct 或 union 中的 struct 或者 union 來說,它們的位元組對齊標準就是它的所有成員中位元組數最大的資料的位元組數。一般情況下 c c ...
C C 中記憶體對齊問題
我們通過幾個例子來全面搞懂c c 中的記憶體對齊問題。來看看下面的結構體大小分別是多大?假設均在32位機器上 struct a 這個相信大家都知道,由於變數都是char型別,對齊值為1,所以結構體大小為3。struct b 對齊值為4,結構體大小為 4 4 8。第乙個4為int,第二個4裡面包含乙個...
C C 結構體 struct 對齊問題
以前只記得結構體對齊,是對齊最長的那個成員,但現在發現並不是這樣,看以下兩個示例 64位 g 9.3.0 編譯 class b 8 static int c 0 static int d 0 static int f 0 cout 值得一提的是靜態成員不佔空間 這裡虛指標 8b,char b 1b。...