C語言位元組對齊

2022-05-22 06:00:10 字數 1285 閱讀 4319

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

編譯器對資料存放做了對齊,平常我們在寫程式的時候都不需要考慮這個問題,但在我們用sizeof求struct結構體的大小的時候,產生的結果往往出乎意料。

現在定義結構體如下:

struct

a;

結構體a裡面定義了乙個4位元組的int變數,乙個1位元組的char變數,乙個2位元組的short變數。

我的編譯器上面是預設的4位元組對齊,所以sizeof(struct a)是 8.

現在又定義如下結構體b

struct

b;

結構體b裡面定義了乙個1位元組的char變數,乙個4位元組的int變數,乙個2位元組的short變數。

但這次sizeof(struct b)是 12

結構體a和結構體b總共的所用的位元組大小都是7位元組,但兩者sizeof運算的結果卻不一樣,這就是位元組對齊的方式有關了。

首先我的gcc編譯器預設是4位元組對齊的。

結構體a首先是定義了乙個4位元組的int變數,與預設對齊一樣,然後定義了乙個1位元組的char變數,最後是乙個2位元組的

short變數,由於第二個char變數只佔了1位元組,而對齊方式是4位元組,所以就空一位元組,把最後定義的2位元組的變數拿

上來補齊。大致的記憶體如下:

所以只有sizeof(struct a) 是 8;

結構體b首先定義了乙個1位元組的char變數,然後定義了乙個4位元組的int變數,最後是乙個2位元組的short變數。

由於中間的是乙個4位元組的int變數,所以不存在補齊,大致的記憶體的如下:

然後在這裡在說一下預編譯指令#pragma pack (value)的用法。這個預編譯指令主要改變編譯器預設的位元組對齊方式,變成指定的value值。

#pragma pack (2)

struct c ;

#pragma pack ()

sizeof(struct c) 是 8。#pragma pack (2) 指定編譯器2位元組對齊,#pragma pack() 還原預設的對齊方式。因為b是4位元組的,其佔的位元組數不會變,然後a和c各佔2位元組,所以總共是8位元組。

c語言位元組對齊

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

C語言位元組對齊

一 概念 對齊跟資料在記憶體中的位置有關。如果乙個變數的記憶體位址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設乙個整型變數的位址為0x00000004,那它就是自然對齊的。二 為什麼要位元組對齊 需要位元組對齊的根本原因在於cpu訪問資料的效率問題。假設上面整型變數的位址不...

C語言位元組對齊

一 概念 對齊跟資料在記憶體中的位置有關。如果乙個變數的記憶體位址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設乙個整型變數的位址為0x00000004,那它就是自然對齊的。二 為什麼要位元組對齊 在c語言中,結構是一種復合資料型別,其構成元素既可以是基本資料型別 如int ...