C 中structure中記憶體對齊方式

2021-08-28 04:47:12 字數 3807 閱讀 5140

2023年10月12日 01:19:24 cainv89 閱讀數:12402 標籤:

結構體復合資料型別

c與c++結構體區別

結構體的作用

結構體的記憶體對齊方式更多

個人分類:

c++基礎

(2)示例**二:

//此宣告宣告了擁有3個成員的結構體,分別為整型的a,字元型的b和雙精度的c,但沒有標明其標籤,宣告了結構體變數s1

struct

s1;//此宣告宣告了擁有3個成員的結構體,分別為整型的a,字元型的b和雙精度的c,結構體的標籤被命名為******,用******標籤的結構體,另外宣告了變數t1, t2[20], *t3

struct ******

;****** t1, t2[20], *t3;

//可以用typedef建立新型別,此宣告宣告了擁有3個成員的結構體,分別為整型的a,字元型的b和雙精度的c,結構體的標籤被命名為******2,用******2作為型別宣告新的結構體變數u1, u2[20], *u3

typedef

struct

******2;

******2 u1, u2[20], *u3;//若去掉typedef則編譯報錯,error c2371: 「******2」: 重定義;不同的基型別

注:在上面的宣告中,第乙個和第二宣告被編譯器當作兩個完全不同的型別,即使他們的成員列表是一樣的,如果令t3=&s1,則是非法的。

注:在一般情況下,tag、member-list、variable-list這3部分至少要出現2個。

(2)示例**二:

#include 

using

namespace

std;

struct sample

}s1;

int main()

=>沒初始化成員變數的情況下:0

初始化成員變數的情況下:7

c++中的結構體與類的區別:

(1)class中預設的成員訪問許可權是private的,而struct中則是public的。

(2)class繼承預設是private繼承,而從struct繼承預設是public繼承。

注:為上面的結構分配空間的時候,vc根據成員變數出現的順序和對齊方式。

(1)先為第乙個成員dda1分配空間,其起始位址跟結構的起始位址相同(剛好偏移量0剛好為sizeof(double)的倍數),該成員變數占用sizeof(double)=8個位元組;

(2)接下來為第二個成員dda分配空間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為8,是sizeof(char)的倍數,所以把dda存放在偏移量為8的地方滿足對齊方式,該成員變數占用sizeof(char)=1個位元組;

(3)接下來為第三個成員type分配空間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為9,不是sizeof(int)=4的倍數,為了滿足對齊方式對偏移量的約束問題,vc自動填充3個位元組(這三個位元組沒有放什麼東西),這時下乙個可以分配的位址對於結構的起始位址的偏移量為12,剛好是sizeof(int)=4的倍數,所以把type存放在偏移量為12的地方,該成員變數占用sizeof(int)=4個位元組;

這時整個結構的成員變數已經都分配了空間,總的占用的空間大小為:8+1+3+4=16,剛好為結構的位元組邊界數(即結構中占用最大空間的型別所占用的位元組數sizeof(double)=8)的倍數,所以沒有空缺的位元組需要填充。所以整個結構的大小為:sizeof(mystruct)=8+1+3+4=16,其中有3個位元組是vc自動填充的,沒有放任何有意義的東西。

(2)示例**二:交換一下上述例子中mystruct的成員變數的位置

struct mystruct

;//錯:sizeof(mystruct)=sizeof(double)+sizeof(char)+sizeof(int)=13。

//對:當在vc中測試上面結構的大小時,你會發現sizeof(mystruct)為24。

注:為上面的結構分配空間的時候,vc根據成員變數出現的順序和對齊方式。

(1)先為第乙個成員dda分配空間,其起始位址跟結構的起始位址相同(剛好偏移量0剛好為sizeof(char)的倍數),該成員變數占用sizeof(char)=1個位元組;

(2)接下來為第二個成員dda1分配空間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為1,不是sizeof(double)=8的倍數,需要補足7個位元組才能使偏移量變為8(滿足對齊方式),因此vc自動填充7個位元組,dda1存放在偏移量為8的位址上,它占用8個位元組;

(3)接下來為第三個成員type分配空間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為16,是sizeof(int)=4的倍數,滿足int的對齊方式,所以不需要vc自動填充,type存放在偏移量為16的位址上,該成員變數占用sizeof(int)=4個位元組;

這時整個結構的成員變數已經都分配了空間,總的占用的空間大小為:1+7+8+4=20,不是結構的節邊界數(即結構中占用最大空間的型別所占用的位元組數sizeof(double)=8)的倍數,所以需要填充4個位元組,以滿足結構的大小為sizeof(double)=8的倍數。所以該結構總的大小為:sizeof(mystruct)為1+7+8+4+4=24。其中總的有7+4=11個位元組是vc自動填充的,沒有放任何有意義的東西。

位元組的對齊方式:在vc中提供了#pragmapack(n)來設定變數以n位元組對齊方式。n位元組對齊就是說變數存放的起始位址的偏移量有兩種情況:第一,如果n大於等於該變數所占用的位元組數,那麼偏移量必須滿足預設的對齊方式;第二,如果n小於該變數的型別所占用的位元組數,那麼偏移量為n的倍數,不用滿足預設的對齊方式。結構的總大小也有個約束條件,分下面兩種情況:如果n大於所有成員變數型別所占用的位元組數,那麼結構的總大小必須為占用空間最大的變數占用的空間數的倍數;否則必須為n的倍數。 

注:vc對結構的儲存的特殊處理確實提高了cpu儲存變數的速度,但有時也會帶來一些麻煩,我們也可以遮蔽掉變數預設的對齊方式,自己來設定變數的對齊方式。

(1)示例**:

#pragmapack(push)//儲存對齊狀態

#pragmapack(4)//設定為4位元組對齊

struct test

;#pragmapack(pop)//恢復對齊狀態

注:以上結構的大小為16,下面分析其儲存情況。

(1)首先為m1分配空間,其偏移量為0,滿足我們自己設定的對齊方式(4位元組對齊),m1占用1個位元組;

(2)接著開始為m4分配空間,這時其偏移量為1,需要補足3個位元組,這樣使偏移量滿足為n=4的倍數(因為sizeof(double)大於n),m4占用8個位元組;

(3)接著為m3分配空間,這時其偏移量為12,滿足為4的倍數,m3占用4個位元組;

這時已經為所有成員變數分配了空間,共分配了16個位元組,滿足為n的倍數。如果把上面的#pragmapack(4)改為#pragma pack(8),那麼我們可以得到結構的大小為24。

c 中結構體structure初始化

1.c structure基本事實 2.初始化問題 3.總結 1.c structure基本事實 c structure為值型別,和class是相類似,但是c 中的class是引用型別。2.初始化問題 下面是兩段 看上去是相似的,但是其中一段 是不能夠編譯的 public struct struct...

c 中結構體structure初始化

1.c structure基本事實 2.初始化問題 3.總結 1.c structure基本事實 c structure為值型別,和class是相類似,但是c 中的class是引用型別。2.初始化問題 下面是兩段 看上去是相似的,但是其中一段 是不能夠編譯的 public struct struct...

對C 中動態記憶體分配的認識

動態記憶體分配需要兩個關鍵字 new和delete。1 new new 用來申請記憶體,這個過程稱為建立。宣告形式 new 資料型別 引數 一二適用 這個語句返回乙個指向記憶體首位址的指標。2 delete 宣告形式 delete 指標名 一二適用 delete 用來刪除new分配的動態記憶體空間,...