作者:billy
版權聲明:著作權歸作者所有,商業轉載請聯繫作者獲得授權,非商業轉載請註明出處
前言
在考慮內存管理之前,我們要先知道資源所佔的內存大小。博主在這裏整理了一些基礎元素所佔的字節大小,防止長時間不接觸而遺忘掉。
基礎類型
cout << sizeof(char) << endl; //1
cout << sizeof(short) << endl; //2
cout << sizeof(int) << endl; //4
cout << sizeof(long) << endl; //4
cout << sizeof(long long) << endl; //8
cout << sizeof(char*) << endl; //32位4個字節,64位8個字節
cout << sizeof(float) << endl; //4
cout << sizeof(double) << endl; //8
這裏有小夥伴經常會問一個問題,爲什麼指針在32位的系統佔4個字節,而在64位系統會佔8個字節呢?
我們知道cpu是無法直接在硬盤上讀取數據的,而是通過內存讀取。cpu通過地址總線、數據總線、控制總線三條線對內存中的數據進行傳輸和操作。
具體流程:
1、cpu通過地址總線,找到該條數據;
2、通過控制總線得知該操作是讀操作還是寫操作;
3、通過數據總線將該數據讀取到cpu或者從cpu寫到內存中;
我們平時所說的計算機是64位、32位、16位,指的是計算機CPU中通用寄存器一次性處理、傳輸、暫時存儲的信息的最大長度。簡單的說32位的操作系統就是指:地址總線是32位的系統。那麼,也就是說操作系統的位數決定了指針變量所佔的字節數。
數組
const char *str1 = "my program";
char str2[] = "my program";
//char str3[10] = "my program"; //error C2117: 'my program' : array bounds overflow
char str4[100] = "my program";
int str5[100];
char str6[] = "abc";
char str7[] = "a\n";
char *str8 = (char *)malloc(100);
void *str9 = (void *)malloc(100);
cout << sizeof(str1) << endl; //4 str1是指向字符串常量的字符指針,sizeof獲得的是一個指針所佔的空間
cout << sizeof(str2) << endl; //11
cout << sizeof(str4) << endl; //100
cout << strlen(str1) << endl; //10
cout << strlen(str2) << endl; //10
cout << strlen(str4) << endl; //10
cout << sizeof(str5) << endl; //400
cout << sizeof(str6) << endl; //4
cout << sizeof(str7) << endl; //3
cout << sizeof(str8) << endl; //4
cout << sizeof(str9) << endl; //4
結構體
struct{
short a; //2
double b //8
char c //1
}A;
struct{
short a; //2
long b //4
}B;
struct{
short a; //2
int b //4
double c //8
}C;
struct{
double a; //8
short b //2
}D;
cout << sizeof(A) << endl; //24
cout << sizeof(B) << endl; //8
cout << sizeof(C) << endl; //16
cout << sizeof(D) << endl; //16
結構體字節對齊的規則如下:
- 結構體中元素按照定義順序依次置於內存中,但並不是緊密排列。從結構體首地址開始依次將元素放入內存時,元素會被放置在其自身對齊大小的整數倍地址上;
- 如果結構體大小不是所有元素中最大對齊大小的整數倍,則結構體對齊到最大元素對齊大小的整數倍,填充空間放置到結構體末尾;
- 基本數據類型的對齊大小爲其自身的大小,結構體數據類型的對齊大小爲其元素中最大對齊大小元素的對齊大小;
類
例1:
class A {};
class B {
int a;
char b;
};
class C: public A {};
class D: public virtual B {};
class E: public A, public B {};
cout << sizeof(A) << endl; //1
cout << sizeof(B) << endl; //8
cout << sizeof(C) << endl; //1
cout << sizeof(D) << endl; //12
cout << sizeof(E) << endl; //8
例2:
class A {
public:
int a;
static int b;
A();
~A();
};
class B {
public:
int a;
char c;
B();
~B();
int add();
static int test();
};
class C {
public:
float a;
char c;
C();
virtual ~C();
virtual void test();
};
class D {
public:
float a;
char b;
double c;
int d;
const double e;
D();
~D();
};
cout << sizeof(A) << endl; //4
cout << sizeof(B) << endl; //8
cout << sizeof(C) << endl; //12
cout << sizeof(D) << endl; //32
總結一下計算一個類對象大小的規律:
- 空類、單一繼承的空類、多重繼承的空類所佔空間大小爲:1個字節;
- 一個類中,虛函數本身、成員函數(包括靜態與非靜態)和靜態數據成員都是不佔用類對象的存儲空間的;
- 當類中聲明瞭虛函數(不管是1個還是多個),那麼在實例化對象時,編譯器會自動在對象裏安插一個指針vPtr指向虛函數表VTable;
- 虛承繼的情況:由於涉及到虛基表,會增加一個vbPtr指針指向虛基表vbTable;
- 在考慮以上內容所佔空間的大小時,還要注意編譯器插入的字節補齊;