天天看點

C語言結構體記憶體對齊

  • 對齊概述
  • 對齊的規則
  • 計算步驟
  • 對比
  • 小結

對齊概述

1.性能原因:為了提高cup的效率通路記憶體的速度,若是通路未對齊的記憶體,處理器需要作兩次通路;而通路對齊的記憶體,則隻需要一次通路。

2.編譯器相關:有的編譯器已經優化了記憶體對齊,是以記憶體對齊依賴于編譯器。

對齊的規則

參考 結構體對齊問題

說實話,規則看起來不太好了解,直接模仿下面步驟即可

計算步驟

以32位機器為例,工具為vs2008

類型 所占位元組
char 1
bool 1
short 2
int 4
long 4
float 4
double 8
指針 4

示例

struct person
    {
        char a;
        double b;
        int c;
        int d;
        char e;
        double f;
        char g;
    };
           

步驟:

1.找出person中位元組數最長的成員b和f,長度為 n = 8;

2.從第一個成員 a 開始計算,将 a 擺在 p = 0x00000 的位置。

3.計算第二個成員 b ,此時 b 的長度為 l = 8 ,其擺放的起始位址 p 需要滿足 p % l = 0 的條件。是以需要在之前填充7個位元組,則 p = 0x00008,其填充0x00008 - 0x00015共八個位元組。

4.計算第三個成員 c ,c 的長度為 l = 4 , 其擺放的起始位址 p = 0x00016, 滿足 p % l = 0,是以不需要在之前填充位元組,其填充0x00016 - 0x00019共四個位元組。

5.下面依次類推。

6.最後計算g,填充一個位元組0x00040。

7.0x00000 - 0x00040共 41 個位元組,總位元組數sum必須滿足 sum % n = 0; n 數值看步驟1,是以最後還需要填充7個位元組,則 sum = 48;

表格示例:

成員 類型 所占位元組 填充位元組數 存儲位址
a char 8 0x00000
b double 1 7 0x00008 - 0x00015
c int 4 0x00016 - 0x00019
d int 4 0x00020 - 0x00023
e char 1 0x00024
f double 8 7 0x00032 - 0x00039
g char 1 0x00040

長度sum = 41,成員變量最長類型所占位元組數 n = 8,為滿足 sum % n = 0,需填充7個位元組,sum = 48;

對比

順序1

struct person2
    {
        double b;
        char a;
        int c;
        int d;
        char e;
        double f;
        char g;
    };
           

将 a 和 b 的順序調換,算出來的長度為 40,

順序2

struct person3
    {
        double b;
        double f;
        int c;
        int d;
        char e;
        char a;
        char g;
    };
           

此時的長度為 32.

小結

由于排列順序不一樣,person3 所占的空間隻有person的 67%,若是使用person結構體存儲資料量有一個GB,那麼使用person3來存儲,隻需要686MB,是以可以從記憶體對齊的角度來優化代碼,節省空間。

此段示例屬于最簡單的那種,還有更複雜的包含數組的,還待研究。。。

繼續閱讀