變數的記憶體分配 記憶體對齊

2021-06-21 09:11:33 字數 2552 閱讀 7804

資料結構還有變數等等都需要占有記憶體,在很多系統中,它都要求記憶體分配的時候要對齊,這樣做的好處就是可以提高訪問記憶體的速度。

#include 

<

iostream

>

2using

namespace

std;34

structx15

;1011struct

x212;17

18struct

x319;24

intmain()25

輸出的結果: 1

long 4

2float 4

3int 4

4char 1

5 x1 的大小 8

6 x2 的大小 12

7 x3 的大小 8

在定義結構體x1,x2,x3時,由於變數的順序不同,而導致分配的記憶體不同

記憶體是乙個連續的塊, 以每4個位元組為乙個對齊單位,來看一下x1,x2,x3在記憶體中的布局

對於x1,第乙個是int型,它佔4個位元組,所以前面4格就滿了,第二個是char型,它佔第二個4位元組組塊的第一格,第三個是char型,它佔第二個4位元組組塊的第二格,因為有記憶體對齊,所以輸出結果為8而不是6.

對於x2,第乙個型別是char型,它占用乙個位元組,所以它首先排在第一組塊的第乙個格仔裡面,第二個是int型別,它占用4個位元組,第一組塊已經用掉一格,還剩3格,肯定是無法放下第二int型別的,因為要考慮到對齊,所以不得不把它放到第二個組塊,第三個型別是char型別,跟第乙個類似。所因為有記憶體分塊對齊,我們的記憶體就不是8個格仔了,而是12個了

當陣列作為函式的引數傳遞時,該陣列自動退化為同型別的指標。

如void funct(char a[100])

而對於

struct {

char a;

double b;

char c; }

這裡記憶體預設對齊位元組數是8位元組,所以結構體所佔的位元組數是24.

深入理解位元組對齊:

結構體是種復合資料型別,其成員由基本資料型別構成(short,int,long,float,double,char),也可以是復合資料型別的資料單元(陣列,聯合,結構等),編譯器為結構的每個成員按自然邊界分配空間 ,各個成員按照它們被宣告的順序在記憶體中順序儲存,為了使cpu對變數加快訪問,變數的起始位址應該具有某種特性,即所謂的對齊,如4位元組的int型,其起始位址應該位於4位元組的邊界上,即能夠被4整除。

位元組對齊的作用:便於cpu快速訪問,利用位元組對齊合理的節省儲存空間

對於32位機器來說,4位元組對齊能夠使cpu的訪問速度提高,如果跨越了4位元組邊界儲存,那麼cpu就要讀取2次,效率降低了。如果在32bit中使用1位元組或2位元組對齊,反而使處理器 速度降低了。所以要考慮處理器的型別。另外,也要考慮 編譯器的型別,vc,gcc預設都是4位元組對齊

更改c編譯器的預設位元組對齊方式:

預設條件下,c編譯器為每個變數或資料單元按自然邊界條件分配空間

1.使用偽指令:#program pack(n)//c編譯器按n個位元組對齊

#program pack()//取消自定義位元組對齊方式

2._attribute(alligned(n)),//讓所有的結構成員對齊在n位元組的自然邊界上,如果結構中有 成員的長  度大於n,則按最大成員的長度來對齊

_attribute_((packed)),//取消編譯過程的優化對齊,按實際占用位元組數對齊。

舉例說明:

struct {

char a;

short b;

float   c;

char d; }

編譯器預設情況下對結構體做自然邊界對齊,結構的第乙個成員a,其偏移位址為0,占用 1個位元組,第二個成員為b,其起始位址必須2位元組對界。因此編譯器在a和b之間填充乙個空位元組,結構的第3個成員和第4個成員恰好落在自然邊界上,在結構中,第3個成員c要求4位元組對齊,為該結構中所有成員要求的最大邊界單元,因而該結構的自然邊界對界條件是4位元組,整個結構所佔空間為12位元組

如新增#program pack(1),整個結構所佔位元組為8位元組

#program pack (2),。。。。。。。。。10位元組

32位機器上各個基本資料型別所佔的長度:

char  1 (有符號無符號相同)

short 2 (有符號無符號相同)

int    4 (有符號無符號相同)

long  4 (有符號無符號相同)

float  4

double  8

編譯器按什麼樣的原則對齊:

首先看一下4個基本概念,

1.資料自身對齊值:char 1,short 2,int long float 4

2.結構體或類的自身對齊值:其成員中自身對齊值最大的那個

3.指定對齊值:#program pack(value) 對齊值為value

4.資料成員,結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個

有效對齊值n是最終決定資料儲存方式的值。有效對齊n,表示「對齊在n上」,也就是說該資料的起始位址%n=0.而資料結構中的資料變數都是按定義的順序來排放的,結構體的成員要對齊,結構題本身也要根據自身的對齊值圓整(就是結構體成員所佔的總長度是結構體有效對齊值的整數倍)

變數的記憶體分配 記憶體對齊

資料結構還有變數等等都需要占有記憶體,在很多系統中,它都要求記憶體分配的時候要對齊,這樣做的好處就是可以提高訪問記憶體的速度。include iostream 2using namespace std 34 structx15 1011struct x212 17 18struct x319 24 ...

記憶體分配時對齊

下面的 載自libxml中的xmlmemmory.c ifdef sun4 define align size 16 else define align size sizeof double endif define hdr size sizeof memhdr define reserve siz...

記憶體分配位址的對齊

void memalign size t boundary,size t size 看nginx源 中的實現 define ngx align d,a d a 1 a 1 返回的位址值為d後第乙個是a的整數倍的值。a是2的整數次冪。假設a 2 n,即a的二進位制表示中末尾有n個0。假設返回的結果為a...