内存分配与数据格式化(malloc与new)
2019獨角獸企業重金招聘Python工程師標準>>>
1. 操作系統內存分配
Linux操作系統內存分配策略采用 伙伴系統與Slab分配器
伙伴系統:按照一定單位大小(4KB),把內存分割成許多連續的內存快,進程每次請求 X塊內存(4X KB)時,就會到空閑鏈表中找到 2*X塊 連續的內存塊,把其中的一半分配給進程,剩下的一半添加到空閑鏈表中(這里X是2的指數倍)
Slab分配器:當進程請求內存小于伙伴系統的最小塊時,為了減小碎片,會將4KB大小的額內存塊通過Slab分配器分割為更小的單位(Byte)
簡而言之,伙伴系統用于分配大塊內存,而Slab用于分配小塊內存
?
2. 數據格式化
為了便于計算機進行處理,我們會將數據進行格式化,也就是用 int、char、long 等數據類型將數據分類,以及構建復雜數據類型 (struct、class)來表示數據
?
3. sizeof 運算符
sizeof運算符的作用就是計算一個類型或變量在內存中實際所占用的空間大小(Byte)
typedef struct __Person {char name[5];char sex [5]; }Person;void func() {cout << sizeof(char) << endl; // output = 1cout << sizeof(int) << endl; // output = 4cout << sizeof(Person) << endl; // output = 10 }?
4. malloc與new?分配內存
extern void *malloc(unsigned int num_bytes);作用是返回固定字節大小的連續內存空間
比如:
typedef struct __Person {char name[5];char sex [5]; }Person;void *pVoid = malloc(sizeof(Person));此時 pVoid 指向的內存大小為 10 個字節,我們可以為這10個字節賦值,然后輸出
char *pChar = (char *)pVoid; char *pStr = "lzb\0\0male\0";// 賦值 for (int i = 0; i < 10; i++) {pChar[i] = pStr[i]; }// 輸出 for (int i = 0; i < 10; i++) {cout << pChar[i] << endl; }//output: //lzb male用 Person對象指針輸出
Person *pPerson = (Person *)pVoid;cout << pPerson->name << endl; cout << pPerson->sex << endl;//output: //lzb //male而我們常用的為對象分配內存與賦值的做法是
void func() {Person *pPerson = (Person *)malloc(sizeof(Person));//賦值strcpy(pPerson->name, "lzb");strcpy(pPerson->sex , "male);//輸出cout << pPerson->name << endl;cout << pPerson->sex << endl; }//output: //lzb //male從上面分析可以得出對象與內存之間的對應關系
以Person對象為例,其實際存儲結構如下
| 成員 | 偏移量 |
| name | 0 |
| sex | 5 |
假設構造了一個Person對象,其內存中的地址為 0x12345678
Peson psn; //假設 &psn = 0x12345678則當我們訪問其各個成員的時候
cout << psn.name << psn.sex << endl;等價于
cout << (char *)(&psn + 0) << (char *)(&psn + 5) << endl; cout << (char *)(0x12345678 + 0) << (char *)(0x12345678 + 5) << endl;所以我們在操作對象的成員的時候,其實是通過 (首地址 + 偏移地址的形式) 操作成員,這也就是用C語言構建復雜數據類型的時候因為成員數據的相互覆蓋而到出錯的原因
typedef struct __Person {char name[5];char sex [5]; }Person;void func() {Person psn;strcpy(psn.name, "lzb123");strcpy(psn.sex, "male");cout << psn.name << endl;cout << psn.sex << endl; }//output: //lzb12male //male這里 name 的長度為5,而 ”lzb123"的長度為 7,這一步操作接受,10個字節的數據如下
l z b 1 2 3 \0 X X X
對 sex 進行賦值后,10個字節的數據內容如下
l z b 1 2 m a l e \0
所以會出現上面的錯誤輸出
?
new與malloc基本相同,不同點在于使用 new 的使用會調用對象的構造函數對內存進行初始化
?
5. 數據對齊
typedef struct __example {char ch1;int tmp;char ch2; }example;sizeof(example) == 12對齊規則不解釋,這里因為內存對齊,導致申請空間的時候,總會有 6Byte 的空間浪費
| 成員 | 偏移量 |
| ch1 | 0 |
| tmp | 4 |
| ch2 | 8 |
也就是說,ch 實際占有空間為 4 個字節,但是我們通過 example->ch 的訪問方式,只能操作 1Byte 的空間大小,所以在構建復雜數據類型的時候,應當對成員順序合理分布,如下所以
typedef struct __example {char ch1, ch2;int tmp; }example;sizeof(example) == 8此時,就只有 2Byte空間的浪費
轉載于:https://my.oschina.net/tigerBin/blog/1538720
總結
以上是生活随笔為你收集整理的内存分配与数据格式化(malloc与new)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么Jedis操作后要主动归还?
- 下一篇: Kubernetes-dashboard