關於類的大小,請先查看:
類和結構體的內存空間佔有問題
簡介
C++類是由結構體發展得來的,所以他們的成員變量(C語言的結構體只有成員變量)的內存分配機制是一樣的。
高字節與低字節,高地址與低地址,大端模式與小端模式
一、高地址與低地址
內存地址對應成16進制,值大的是高地址,反之爲低地址。
二、高字節與低字節
如int a=16777220,化爲十六進制是0x01 00 00 04則04屬於低字節,01屬於高字節
三、大端模式與小端模式
大端模式:高字節存放在低地址
小端模式:高字節存放在高地址
四、存放順序
- 一個整數類型內部
低地址存儲低位,高地址存儲高位。比如int a=1,則存儲情況爲0000(高地址) 0000 0000 0001(低地址) - 若干個局部變量(在棧中存儲的)
先定義的高地址,後定義的低地址 - 類、結構體或數組的元素
先定義的低地址,後定義的高地址
一
union U {
char cp[2];
short sp;
};
int main(int argc, char *argv[])
{
U temp;
temp.cp[1] = 1;
temp.cp[0] = 3;
cout << temp.sp << endl;
return 0;
}
結果:
259 // 0x0103 小端模式
二
int main(int argc, char *argv[])
{
int a;
char b;
int c;
short d;
long int e = 1;
char *p;
cout << "int &a = " << (size_t)&a << endl;//結果1
cout << "char&b = " << (size_t)&b << endl;//結果2
cout << "int &c = " << (size_t)&c << endl;//結果3
cout << "short&d = " << (size_t)&d << endl;//結果4
cout << "long &e = " << (size_t)&e << endl;//結果5
cout << "char*&p = " << (size_t)&p << endl;//結果6
char temp[16]={0};
memcpy(temp, &p, 16);
cout << (size_t)p << endl;
for ( int i = 0; i < 16; i++) {
cout << (int)temp[i] << " ";
}
cout << endl;
return 0;
}
結果:
int &a = 140722993149544
char&b = 140722993149543
int &c = 140722993149536
short&d = 140722993149534
long &e = 140722993149520
char*&p = 140722993149512
4233981
-3 -102 64 0 0 0 0 0 1 0 0 0 0 0 0 0
分析:
可以看見,局部變量從高地址開始分配,到低地址。
結果1 > 結果2 > 結果3 > 結果4 > 結果5 > 結果6
結果1 - 結果2 = 140722993149544 - 140722993149543 = 1B
//一個char佔一個字節的內存
結果3 + 4B = 140722993149540
//一個字節的變量必須對齊,填充三個字節
結果5 - 結果6 = 140722993149520 - 140722993149512 = 8B
/*
char *佔4個字節,但是內存分配了8個字節;
我們把內存打印出來:
4233981
-3 -102 64 0 0 0 0 0 1 0 0 0 0 0 0 0
可以看見,指針後面自帶了一個字節的空字符
*/
三
單個指針和數組名指針有一點不同,那就是
單個指針有一個存儲空間,且自帶'\0'
結束符(如上),它的存儲內容和地址不一樣的
char *p;
&p != p
數組名指針,它的指向的地址都是在數組首地址
char a[10];
&a == a;
四
關於數組聲明後再內存中的分配問題,作者實驗了很久,發現同樣的代碼,連續幾次編譯後得到的結果,都是不一樣的。
尤其是當有int[]
數組時,甚至出現違背第二條內存分配原則,int[]
數組總是被分配在最低的地址處。
作者猜測,這應該和編譯器優化掛鉤的。
虛函數
有虛函數的類裏,有一張虛函數表,這張表裏是每個虛函數的函數指針。對,它的大小就是所有指針加起來的大小。
這些指針放在類實例地址的低地址,也就是類對象頭部。
然後就是各個變量。
派生類
如上圖,子類實例化後的結構。
他有多少個父類每個父類的大小加起來在加上自身就是sizeof的大小。
話句話說,對於子類,最開始的內存數據記錄着父類對象的拷貝(包括父類虛函數表指針和成員變量)。 之後是子類自己的成員變量數據。