C 記憶體對齊

2021-06-18 13:31:54 字數 2951 閱讀 6648

在c語言和c++語言中相信很多人都有使用過sizeof(),這個帖子主要偏向於交流獲取class和struct的位元組數時候的問題。

我使用的是windows 7的32位os 和 vs2010的旗艦版

先來一些正常的

[cpp]view plain

copy

struct

tests  

;  class

testc  

};  

intmain()    

這個時候相信大家都能想到輸出的結果是

從這裡我們可以看到我們用sizeof()取struct和class的位元組的時候只有他們的成員變數才算進去的,方法及其內部的變數是不算的。當然了,乙個空類是預設1位元組的。

接下來我們來做一些「不正常」的

[cpp]view plain

copy

struct

tests  

;  class

testc  

};  

intmain()    

我們這次只是調換了一下成員變數的位置,然後我們再次執行一下檢視結果。

很奇怪的結果,這個的執行結果不是我們正常想象的結果。這是為什麼呢?

原來struct和class中為變數分配空間是以結構中最長資料元素為對齊方式的。

例如之前我們看過的例子(class 和 struct一樣我們就以struct為例):

tests 一:

變數          分配空間(位元組)          占用空間(位元組)          起始位址

bool a                  4                                  1                            1

char b                 0                                  1                            2

short c                0                                  2                            3

int d                   4                                  4                            5

通過這個我們可以看到分配空間是以最高的int為主的,如果可以填充的話就填充。sizeof(tests) = 8

tests  二:

變數          分配空間(位元組)          占用空間(位元組)          起始位址

char b                  4                                  1                            1

short c                 0                                  2                            2

int d                    4                                  4                            5

bool a                   4                                  1                            9

比之前我們只是將變數a調換到了最後,但是整個空間分配就和之前的不一樣了。sizeof(tests) = 12

通過這兩次的圖表對比大家可以了解是什麼原因導致這個結果了吧。。

記憶體對齊的規則:

1、  對於結構的各個成員,第乙個成員位於偏移為0的位置,以後每個資料成員的偏移量必須是min(#pragma pack()指定的數,這個資料成員的自身長度) 的倍數。

2、  在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行對齊。

#pragma pack(n) 表示設定為n位元組對齊。 vc6預設8位元組對齊

在判斷如何對齊的時候,我們可以根據偏移量和自身型別的sizeof的倍數來決定例如:

[cpp]view plain

copy

struct

tests  

;  

在給char b申請記憶體時偏移量為0,是sizeof(char)的倍數直接分配。

在給int c申請記憶體時偏移量為1,不是sizeof(int)的倍數所以要填充3個位元組讓偏移量達到4成為sizeof(int)的倍數然後為其分配記憶體。

在給double d申請記憶體時偏移量為8時sizeof(double)的倍數,直接分配。

所以最後sizeof(tests)的結果是16

[cpp]view plain

copy

struct

tests  

;  

在tests中按照上面描述的方法進行分配記憶體。

分配int c時偏移量為0直接分配

分配char b時偏移量為4直接分配

那麼sizeof(tests)就是5了嗎?    結果顯然不是的··········

這只是完成了資料成員的記憶體對齊,還沒有做結構本身的記憶體對齊。按照結構本身的對齊規則來說,我們要取出所有成員和#pragma pack指定的數值中較小的乙個得倍數來對齊結構。所以sizeof(tests)的結果是8

C 記憶體對齊

vc6.0編譯器對記憶體對齊的管理方式遵循以下兩個原則 1.對於結構體內部變數的對齊方式 變數存放的起始位址相對於結構的起始位址的偏移量 char 偏移量必須為sizeof char 即1的倍數 int 偏移量必須為sizeof int 即4的倍數 float 偏移量必須為sizeof float ...

c 記憶體對齊

一.計算struct的size有兩個原則 pragma pack n n是編譯器的對齊位元組數 1 struct中各成員按照對齊原則 在為當前變數 設為a 分配記憶體時,要參考之前所有變數的偏移量之和 設為d d必須是min n,sizeof a 的倍數,否則編譯器會自動在最後補上缺少的位元組數。2...

C 記憶體對齊

c 中的記憶體對齊 記憶體對齊 在我們的程式中,資料結構還有變數等等都需要占有記憶體,在很多系統中,它都要求記憶體分配的時候要對齊,這樣做的好處就是可以提高訪問記憶體的速度。我們還是先來看一段簡單的程式 程式一 1 include 2 using namespace std 3 4structx1 ...