程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++裡的對齊規則

C++裡的對齊規則

編輯:關於C++

什麼是對齊?
在C/C++中,數據結構或類的成員變量,並不是按照它們的大小,一個一個緊湊地排列在空間上的。它們是按照一種特定的方法排列的,有可能在兩個成員變量之間插入一個或個byte,以保證每個成員變量的起始位置是都是從某些特定的位置開始的。這就是對齊。單純從語言上描述對齊有些枯燥難以理解,下文將配以例子說明C/C++是基於什麼樣的規則對齊的。

為什麼要對齊?
在大多數平台上,系統從某些特定的位置開始讀數據非常快,而從其它位置讀數據會慢很多。C/C++是一種注重效率的語言,為了使程序速度盡可能地快,選擇犧牲很少的空間,用填充byte的方式保證所有數據的存儲都從這些特定的位置開始,而達到較高的運行速度。

什麼是4字節對齊?
當說到一個結構體n字節對齊,包含2個信息:
(1)結構體的起始地址能被n整除
(2)結構體的總大小能被n整除
當說到一個成員變量是n字節對齊的,說明該變量的起始地址能被n整除。比如某變量的對齊字節數是4,那麼它的首地址的16進制形式一定是以0/4/8/C結尾的。
在實際場景中,n可以是1、2、4、8


規則開始啦。

1.在64位系統中,默認的對齊字節是8。在32位系統中,網上查到的資料有說4也有說8,因為用的是64位系統,沒有驗證過32位的情況。

struct type
{
    int a;
    long b;
};

int main()
{
    type t;
    cout<

運行結果:

size = 16
address a = 0x7fffa0b9e9d0
address b = 0x7fffa0b9e9d8

排列方式:
a a a a 0 0 0 0
b b b b b b b b

2.對於整個結構體而言,其整個大小也必須是字節數的倍數,如果不足,後面補充

struct type
{
    long a;
    int b;
};

int main()
{
    type t;
    cout<

運行結果:

size = 16
address a = 0x7ffff8bb0840
address b = 0x7ffff8bb0848

排列方式:
a a a a a a a a
b b b b 0 0 0 0

3.可以通過#pragma pack修改默認值,但只能改小,不能改大。

#pragma pack (4)

struct type
{
    long a;
    int b;
};

int main()
{
    type t;
    cout<

運行結果:

size = 12
address a = 0x7fffe365d4d0
address b = 0x7fffe365d4d8

排列方式:
a a a a
a a a a
b b b b

4.
對於結構體或類中的某一個成員變量而言,它的對齊按照 #pragma pack指定的數值和這個數據成員自身長度中,比較小的那個進行。
a=數據成員自動長度
b=默認值,取值范圍為1,2,4,8
該數據成員對齊字節=min(a,b)

struct type
{
    bool a;
    int b;
};

int main()
{
    type t;
    cout<

運行結果:

size = 8
address a = 0x7fff43062ed0
address b = 0x7fff43062ed4

排列方式:
a 0 0 0
b b b b

5.
對於一個結構體,它的對齊字節取取決於結構中最大的成員與#pragma pack指定的數值
a=結構中最大的數據成員的自動長度
b=默認值,取值范圍為1,2,4,8
該結構體對齊字節=min(a,b)

struct type
{
    int a;
    bool b;
};

int main()
{
    type t;
    cout<

運行結果:

size = 8
address a = 0x7fff518d64a0
address b = 0x7fff518d64a4

排列方式:
a a a a
b 0 0 0

6.
默認值等於或超過所有數據成員長度的時候,默認值的大小將不產生任何效果。
a=max(所有數據成員長度)
b=默認值,取值范圍為1,2,4,8
If(b>a)
該結構體對齊字節數為a

7.結構體包含結構體的情況
若某一成員變量是另一個結構體,該成員變量的對齊字節數為成員變量結構體的對齊字節數
例1:

struct byte3
{
    char a;
    char b;
    char c;
};

struct type
{
    byte3 a;
    byte3 b;
    byte3 c;
};

int main()
{
    type t;
    cout<

運行結果

size = 9
address a = 0x7fff6346cdf0
address b = 0x7fff6346cdf3
address c = 0x7fff6346cdf6

說明:
由於所有結構體中最大的字節長度是1,所以是1字節對齊的。雖然有一個結構體的大小是3,但是還是按照1對齊的。
例2:

struct byte3
{
    short a;
    char b;
};

struct type
{
    byte3 a;
    byte3 b;
    byte3 c;
};

int main()
{
    type t;
    cout<

運行結果:

size = 12
address a = 0x7fffff3f1ef0
address b = 0x7fffff3f1ef4
address c = 0x7fffff3f1ef8

說明:
由於所有結構體中最大的字節長度是1,所以結構體之間是2字節對齊的。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved