日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于C语言中的结构体内存对齐与位段问题

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于C语言中的结构体内存对齐与位段问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

  • 結構體的內存對齊與位段
  • 一、結構體的內存對齊
    • 1.為什么會有內存對齊?
    • 2.如何內存對齊
    • 3. 如何在設計結構體的時候,既要滿足對齊,又要節省空間
  • 二、位段
    • 1.什么是位段
    • 2.位段的內存分配
    • 3.位段的跨平臺問題
  • 總結


結構體的內存對齊與位段

一、結構體的內存對齊

1.為什么會有內存對齊?

為了計算結構體的大小,首先要了解的就是結構體內存對齊。那么為什么會存在內存對齊呢,大部分參考資料如是說:

  • 平臺原因(移植原因): 不是所有的硬件平臺都能訪問任意地址上的任意數據的;某些硬件平臺只能
    在某些地址處取某些特定類型的數據,否則拋出硬件異常。
  • 性能原因: 數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在于,為了訪問未對齊的
    內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問。
  • #舉個例子:對于有32根地址總線的計算機來說,每次讀取的單位是4個字節,假入定義了如下結構體:

    struct s1 { char c1; int i; char c2; }

    由于c1占1個字節,i占4個字節,c2占1個字節,所以計算機在讀取時候,會先讀取c1和i的3個字節(共四個字節)、再讀取i的最后一個字節和c2。因此計算器不但需要進行兩次內存讀取,并且還需要對i的數據進行拼接,無形中浪費了運行的時間。所以為了減少時間的浪費,就采用了內存對齊的方式。
    總的來說:內存對齊是一種拿空間來換取時間的方法。

    2.如何內存對齊

    首先需掌握內存對齊的規則:

  • 第一個成員在與結構體變量偏移量為0的地址處。
  • 其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。
    對齊數 = 編譯器默認的一個對齊數與該成員大小的較小值。
    VS中默認的值為8
  • 結構體總大小為最大對齊數(每個成員變量都有一個對齊數)的整數倍。
  • 如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整
    體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。
    拿上面的定義的結構體試試:

  • 如圖,藍色的部分是開辟的字節數(其中c1,i,c2分別為1 , 4,1個字節),紅色為經過內存對齊規則部位的字節數。
    可見該結構體共占用12個字節,需讀取3次。

    3. 如何在設計結構體的時候,既要滿足對齊,又要節省空間

    答案是: 讓占用空間小的成員盡量集中在一起
    繼續以上面的結構體為例;我們定義的結構體成員不變,只改變次序試試:

    struct s1 { char c1; char c2;` int i; }

    計算下該結構體的大小:

    可以看到,經過改良的定義形式,該結構體只占用了8個字節的大小,且只讀取兩次。

    二、位段

    1.什么是位段

    位段一般在嵌入式開發和底層開發使用,目的是大大節省內存空間。
    位段的聲明和結構是類似的,有兩個不同:
    1.位段的成員必須是 int、unsigned int 或signed int 。
    2.位段的成員名后邊有一個冒號和一個數字。
    比如:

    struct A {int _a:2;int _b:5;int _c:10;int _d:30; };

    成員名后的數字表示的是可開辟的位數。

    2.位段的內存分配

  • 位段的成員可以是 int unsigned int signed int 或者是 char (屬于整形家族)類型
  • 位段的空間上是按照需要以4個字節( int )或者1個字節( char )的方式來開辟的。
  • 位段涉及很多不確定因素,位段是不跨平臺的,注重可移植的程序應避免使用位段。
  • #舉個例子

    struct S {char a:3;char b:4;char c:5;char d:4; }; struct S s = {0}; s.a = 10; s.b = 12; s.c=3; s.d=4;

    以上代碼中的結構體空間是如何開辟的呢?
    分配情況如下圖所示:
    a,b,c,d各自分配四個3、4、5、4個位,8個位代表一個字節,所以a和b分配在一個字節中,c和d各占一個字節。
    同時位段還存在截斷問題,如上述結構體中a只分配了3個位,但s.a=10,10的二進制數為1010;因此就會將第一個1截斷成為010;再與b結合就成了01100010.

    3.位段的跨平臺問題

  • int 位段被當成有符號數還是無符號數是不確定的。
  • 位段中最大位的數目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機
    器會出問題。
  • 位段中的成員在內存中從左向右分配,還是從右向左分配標準尚未定義。
  • 當一個結構包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是
    舍棄剩余的位還是利用,這是不確定的。
  • 總結

    以上就是C語言中的結構體內存和位段問題的一些討論,感謝觀看,歡迎指正!

    總結

    以上是生活随笔為你收集整理的关于C语言中的结构体内存对齐与位段问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。