日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

c/c++--字節對齊(byte alignment)

作者:LtMamba 更新時間: 2023-10-14 編程語言

1. 默認字節對齊

  • 在所有結構體成員的字節長度都沒有超出操作系統基本字節單位(32位操作系統是4,64位操作系統是8)的情況下
    按照結構體中字節最大的變量長度來對齊;
  • 若結構體中某個變量字節超出操作系統基本字節單位
    那么就按照系統字節單位來對齊

注意:
并不是32位就直接按照4個字節對齊,64位就按照8個字節對齊。

2. 為什么存在字節對齊

2.1 了解 CPU 一次讀取內存數

CPU 一次能讀取多少內存要看數據總線是多少位

  • 如果是16位,則一次只能讀取 2 個字節
  • 如果是32位,則可以讀取 4 個字節,并且 CPU 不能跨內存區間訪問

例子:

假設有這樣一個結構體如下:

struct st3
{
    char a;
    int b;
};
//在32位系統下,它就應該是8個字節的。

假設地址空間是類似下面這樣的:
在這里插入圖片描述

  • 在沒有字節對齊的情況下

    1. 變量 a 就是占用了 0x00000001 這一個字節,而變量b則是占用了 0x00000002~0x000000005 這四個字節
    2. 此時 cpu 如果想從內存中讀取變量 b,首先要從變量 b 的開始地址 0x00000002讀到 0x0000004,然后再讀取一次 0x00000005 這個字節,相當于讀一個 int,cpu 從內存讀取了兩次
  • 如果進行字節對齊的話

    1. 變量 a 還是占用了 0x00000001 這一個字節,而變量 b 則是占用了 0x00000005~0x00000008 這四個字節
    2. 此時 cpu 要讀取變量 b 的話,就直接一次性從 0x00000005 讀到 0x00000008 ,就一次全部讀取出來了。

總結:

  • 字節對齊的根本原因其實在于 cpu 讀取內存的效率問題,對齊以后,cpu讀取內存的效率會更快。
  • 對齊的時候 0x00000002~0x00000004 這三個字節是浪費的,所以字節對齊實際上也有那么點以空間換時間的意思,具體寫代碼的時候怎么選擇,其實是看個人的。

3. 編碼時手動設置對齊

兩種。

3.1 代碼里添加預編譯標識 pragma pack(n)

3.1.1 用法

  • 使用預編譯指令 #pragma pack (n) 來告訴編譯器,使用我們指定的對齊值來取代缺省的。
  • 對齊的算法: 隨編譯器變化
//用法如下
#pragma pack(n)//表示它后面的代碼都按照n個字節對齊
struct st3
{
    char a;
    int b;
};
#pragma pack()//取消按照n個字節對齊,是對#pragma pack(n)的一個反向操作

3.1.2 例子

#include <stdio.h>

#pragma pack(1)//表示它后面的代碼都按照n個字節對齊
struct st3
{
    char a;
    int b;
};
#pragma pack()//取消按照n個字節對齊,是對#pragma pack(n)的一個反向操作

#pragma pack(2)//表示它后面的代碼都按照n個字節對齊
struct st4
{
    char a;
    int b;
};
#pragma pack()//取消按照n個字節對齊,是對#pragma pack(n)的一個反向操作

int main()
{
   	
    printf("%d\n",sizeof(struct st3) );
    printf("%d\n",sizeof(struct st4) );
	
   	return 0;
}

在這里插入圖片描述

3.2 定義結構體時指定__attribute__((packed))

3.2.1 用法

  • __attribute__ ((packed)) 的作用就是告訴編譯器取消結構在編譯過程中的優化對齊,按照實際占用字節數進行對齊,是GCC特有的語法。這個功能是跟操作系統沒關系跟編譯器有關.
//用法如下
struct bbb
{
   char a;
   int b;
}__attribute__((packed));//直接按照實際占用字節來對齊,其實就是相當于按照1個字節對齊了
//這里計算sizeof(st3)=5

3.2.2 例子

#include <stdio.h>

struct st3
{
   char a;
   int b;
}__attribute__((packed));

struct __attribute__((packed)) st4
{
	int b;
	char a;
};

int main()
{
   	
    printf("%d\n",sizeof(struct st3) );
    printf("%d\n",sizeof(struct st4) );
	
   	return 0;
}

在這里插入圖片描述

原文鏈接:https://blog.csdn.net/qq_37233070/article/details/133791709

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新