日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C++ 结构体内存对齐

發布時間:2023/12/20 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 结构体内存对齐 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

剛出學校那會,出去找實習工作,面試答題被問到結構體內存大小的問題,雖然自己以前接觸過,但是也還是答錯了,最終面試的這份工作黃了。一年后的最近,還是在找工作的路上,面試了一家游戲公司,其中也是答題環節有一道題被問到結構體的內存大小,也還是答錯了,最后面試也還是黃了。

到了現在自己才醒悟過來,這些知識點是有多么的重要,所以咬緊牙,把這個內容的知識點啃下來,寫下這篇博客記錄下來!


先看一段簡單的程序

#include <iostream>using namespace std;typedef struct A {char c;int i; };typedef struct B {char c;int i;double d; };typedef struct C {char c;int i;double d;char c1; };int main(void) {cout << "struct A size = " << sizeof(struct A) << endl;cout << "struct B size = " << sizeof(struct B) << endl;cout << "struct C size = " << sizeof(struct C) << endl;return 0; }

如果不運行,那么大家知道結構體A、B、C所占用的內存大小是多少嗎?

運行截圖:

以上輸出的結果并非實際成員占用的字節數,這就是結構體的內存對齊!

按照我們正常的邏輯,結構體A的內存大小應該是5個字節,結構體B的內存大小應該是13個字節,結構體C的內存大小應該是14字節才對!
但是為什么是8、16和24呢?將在下面進行講解。

結構體內存對齊原因

  • 平臺原因(移植原因):
    “不是所有的硬件平臺都能訪問任意地址上的任意數據;某些硬件平臺只能在某些特定地址處取某些特定的數據,否則就會拋出硬件異常”。也就是說在計算機在內存讀取數據時,只能在規定的地址處讀數據,而不是內存中任意地址都是可以讀取的。

  • 效率原因:
    正是由于只能在特定的地址處讀取數據,所以在訪問一些數據時,對于訪問未對齊的內存,處理器需要進行兩次訪問;而對于對齊的內存,只需要訪問一次就可以。 其實這是一種以空間換時間的做法,但這種做法是值得的。

  • 結構體對齊規則

  • 第一個成員在結構體變量偏移量為0 的地址處,也就是第一個成員必須從頭開始。

  • 其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。對齊數為編譯器默認的一個 對齊數與該成員大小中的較小值。vs中默認值是8 Linux默認值為4(可以通過#pragma pack (N) 修改,使用#pragma pack(show) 可以查看對齊值),但修改時N的取 值只能設置成1, 2,4,8,16.

  • 結構體總大小為最大對齊數的整數倍。(每個成員變量都有自己的對齊數)

  • 如果嵌套結構體,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是 所有最大對齊數(包含嵌套結構體的對齊數)的整數倍。(具體詳情,請看下面代碼結構體G)

  • 結構體對齊的規則都是依據上面四條規則進行的!

    結構體對齊示例

    typedef struct A {char c;int i; };

    根據第二和第三條規則,VS中最大默認對齊數是8,結構體中最小的是int類型的4,8 < 4,所以結構體A的對齊數是4.
    所以即使char類型占一個字節,但是他在內存中也會占用4個字節,來對齊4字節數,這就是所謂的,犧牲空間來換取時間!

    后面的也是一樣的道理!

    如果是這樣的結構體,那么他們的內存將會是多少呢?

    typedef struct D {char c;int i;double d;char c1;int b;char c2; };typedef struct E {int i;double d;char c;double d2; };typedef struct F {int i;double d;char c;double d2;int i2;int i3;char c2;char c3;char c4;int i4; };typedef struct G {int i;double d;struct E e;char c;double d2; };


    下面是他們的內存關系圖:


    上述四張圖基本涵蓋了所有情況,希望這四張圖大家能看明白是怎么個回事!

    我本人的理解
    以它為例,

    typedef struct D {char c;int i;double d;char c1;int b;char c2; };

    首先我會先找到結構體中最大的變量字節大小(內部結構體除外),然后使用加法原則向其對齊。(結構體D的對齊數是8)
    c 是1個字節,i是4個字節,c + i 等于5字節,為了符合內存對齊的原則,他倆占用最前方8個字節的內存,當然c是占4個字節,i也是占4個字節,這樣4 + 4 等于8,才符合內存對齊。
    d是8個字節,緊接著后面存儲8個字節。
    c1是一個字節,b是4個字節,計算規格和上面一樣,占用8個字節。
    最后剩余一個c2是一個字節,當然為了符合內存對齊的原則他在結構體中是占8個字節的。
    所以最后計算出內存大小為:
    (c + i) == 8(字節)
    d == 8(字節)
    (c1 + b) == 8(字節)
    c2 == 8(字節)
    8 + 8 + 8 + 8 == 32(字節)

    相信再配合下圖,一定可以理解是什么原理的:


    總結
    結構體內存對齊這是比較底層的知識點了,當然這也是我們程序員需要掌握的,特別是服務器開發人員。
    對齊時需要注意對齊數!

    總結

    以上是生活随笔為你收集整理的C++ 结构体内存对齐的全部內容,希望文章能夠幫你解決所遇到的問題。

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