C++如何計算結構體與對象的大小
如何計算結構體的大小
其實計算一個結構的大小的方法并不難,簡單來說就是把結構體內的所有成員的大小相加就可以。但是,需要內存對齊那么究竟什么是內存對齊,又為什么要進行類型對齊呢?
結構體的內存對齊
結構體內存對齊主要有兩個步驟:
1.結構體各成員對齊.
2.結構體總體對齊
結構體內存對齊規(guī)則:
1.結構體的第一個成員在存放在結構體偏移量為0的位置
2.其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。.
對齊數(shù) = 編譯器默認的一個對齊數(shù)與該成員大小的較小值。 /* **VS中默認的值為8 **Linux中的默認值為4 */
3.結構體總大小為最大對齊數(shù)(每個成員變量都有一個對齊數(shù))的整數(shù)倍。
4.如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結構體的整體大小就是所有最大對齊數(shù)(含嵌套結構體的對齊數(shù))的整數(shù)倍。
說了這么多,我們直接在VS環(huán)境下舉幾個例子給大家說明一下:
例1:
struct S1
{
char c1;
int i;
char c2;
};
(1)計算這個結構體的大小的時候,首先看c1的大小是1(char類型),也即是說在結構體中c1存放的位置是結構體偏移量是0的位置
(2)接下來看i占4個字節(jié),根據(jù)結構體對齊規(guī)則可知,c的有效對齊值為4(4 < 8)對齊到4的整數(shù)倍地址,即地址偏移量為4處.(40的位置存放了c1,所以只能從41的位置開始存放)
(3)同(2)得出c2的存儲位置是8
(4)此時內存中共有9個字節(jié),進行結構體整體對齊,最大對齊數(shù)是4,即要求是4的整數(shù)倍,也就是12

例2:
struct S1
{
char c1;
int i;
char c2;
};
struct S2
{
char a1;
struct S1 s1;
int i;
};
上面我們知道S1的大小是12,現(xiàn)在我們計算一下S2的大?。?/p>
(1)a1占一個字節(jié),放在結構體變量偏移量為0 的地址處.
(2) s1占12個字節(jié),對齊數(shù)位4(嵌套的結構體對齊到自己的最大對齊數(shù)的整數(shù)倍處,S1的最大對齊數(shù)是4),40處存放了a1,所以只能從41處開始存放
(3)i占了4字節(jié),對齊數(shù)為4,s1一直存放到了15的位置,所以i只能從4*5 = 20的位置開始存儲
(4)現(xiàn)在內存中共有20個字節(jié),成員中最大對齊數(shù)是4,整體對齊時為4的倍數(shù),所以結果是20

注意:默認對齊參數(shù)是可以用#pragma pack()設置的,例如下面的這個例子
#include <stdio.h>
#include <Windows.h>
#pragma pack(8)//設置默認對齊數(shù)為8
struct S1
{
char c1;
int i;
char c2;
};
#pragma pack()//取消設置的默認對齊數(shù),還原為默認
#pragma pack(1)//設置默認對齊數(shù)為1
struct S2
{
char c1;
int i;
char c2;
};
#pragma pack()//取消設置的默認對齊數(shù),還原為默認
int main()
{
//輸出的結果是什么?
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
system("pause");
return 0;
}

為什么存在內存對齊
1.平臺原因(移植原因): 不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。
2. 性能原因: 數(shù)據(jù)結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在于,為了訪問未對齊的內存,處理器
需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問
如何計算一個對象的大小
其實在C++中,結構體和類可以認為是相同的,只是默認的訪問權限不同(struct默認是public,class默認是private ),從這方面來看的話,其實計算一個類/對象的大小的方法和計算結構體的大小的方法是一樣的。
我們來驗證一下:
#include <iostream>
using namespace std;
struct A
{
int a;
char b;
char c;
};
class B
{
int a;
char b;
char c;
};
int main()
{
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
system("pause");
return 0;
}

可以看到,我們對結構體A和類B計算大小是一樣的。
總結
到此這篇關于C++如何計算結構體與對象大小的文章就介紹到這了,更多相關C++計算結構體對象大小內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言fprintf()函數(shù)和fscanf()函數(shù)的具體使用
本文主要介紹了C語言fprintf()函數(shù)和fscanf()函數(shù)的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11
VS2019使用Windows桌面應用程序模塊創(chuàng)建Win32窗口
這篇文章主要介紹了VS2019使用Windows桌面應用程序模塊創(chuàng)建Win32窗口,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04

