日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

内存分配与数据格式化(malloc与new)

發(fā)布時間:2025/3/18 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存分配与数据格式化(malloc与new) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

1. 操作系統(tǒng)內(nèi)存分配

Linux操作系統(tǒng)內(nèi)存分配策略采用 伙伴系統(tǒng)與Slab分配器

伙伴系統(tǒng):按照一定單位大小(4KB),把內(nèi)存分割成許多連續(xù)的內(nèi)存快,進程每次請求 X塊內(nèi)存(4X KB)時,就會到空閑鏈表中找到 2*X塊 連續(xù)的內(nèi)存塊,把其中的一半分配給進程,剩下的一半添加到空閑鏈表中(這里X是2的指數(shù)倍)

Slab分配器:當(dāng)進程請求內(nèi)存小于伙伴系統(tǒng)的最小塊時,為了減小碎片,會將4KB大小的額內(nèi)存塊通過Slab分配器分割為更小的單位(Byte)

簡而言之,伙伴系統(tǒng)用于分配大塊內(nèi)存,而Slab用于分配小塊內(nèi)存

?

2. 數(shù)據(jù)格式化

為了便于計算機進行處理,我們會將數(shù)據(jù)進行格式化,也就是用 int、char、long 等數(shù)據(jù)類型將數(shù)據(jù)分類,以及構(gòu)建復(fù)雜數(shù)據(jù)類型 (struct、class)來表示數(shù)據(jù)

?

3. sizeof 運算符

sizeof運算符的作用就是計算一個類型或變量在內(nèi)存中實際所占用的空間大小(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?分配內(nèi)存

extern void *malloc(unsigned int num_bytes);

作用是返回固定字節(jié)大小的連續(xù)內(nèi)存空間

比如:

typedef struct __Person {char name[5];char sex [5]; }Person;void *pVoid = malloc(sizeof(Person));

此時 pVoid 指向的內(nèi)存大小為 10 個字節(jié),我們可以為這10個字節(jié)賦值,然后輸出

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

而我們常用的為對象分配內(nèi)存與賦值的做法是

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

從上面分析可以得出對象與內(nèi)存之間的對應(yīng)關(guān)系

以Person對象為例,其實際存儲結(jié)構(gòu)如下

成員偏移量
name0
sex5

假設(shè)構(gòu)造了一個Person對象,其內(nèi)存中的地址為 0x12345678

Peson psn; //假設(shè) &psn = 0x12345678

則當(dāng)我們訪問其各個成員的時候

cout << psn.name << psn.sex << endl;

等價于

cout << (char *)(&psn + 0) << (char *)(&psn + 5) << endl; cout << (char *)(0x12345678 + 0) << (char *)(0x12345678 + 5) << endl;

所以我們在操作對象的成員的時候,其實是通過 (首地址 + 偏移地址的形式) 操作成員,這也就是用C語言構(gòu)建復(fù)雜數(shù)據(jù)類型的時候因為成員數(shù)據(jù)的相互覆蓋而到出錯的原因

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個字節(jié)的數(shù)據(jù)如下

l z b 1 2 3 \0 X X X

對 sex 進行賦值后,10個字節(jié)的數(shù)據(jù)內(nèi)容如下

l z b 1 2 m a l e \0

所以會出現(xiàn)上面的錯誤輸出

?

new與malloc基本相同,不同點在于使用 new 的使用會調(diào)用對象的構(gòu)造函數(shù)對內(nèi)存進行初始化

?

5. 數(shù)據(jù)對齊

typedef struct __example {char ch1;int tmp;char ch2; }example;sizeof(example) == 12

對齊規(guī)則不解釋,這里因為內(nèi)存對齊,導(dǎo)致申請空間的時候,總會有 6Byte 的空間浪費

成員偏移量
ch10
tmp4
ch28

也就是說,ch 實際占有空間為 4 個字節(jié),但是我們通過 example->ch 的訪問方式,只能操作 1Byte 的空間大小,所以在構(gòu)建復(fù)雜數(shù)據(jù)類型的時候,應(yīng)當(dāng)對成員順序合理分布,如下所以

typedef struct __example {char ch1, ch2;int tmp; }example;sizeof(example) == 8

此時,就只有 2Byte空間的浪費

轉(zhuǎn)載于:https://my.oschina.net/tigerBin/blog/1538720

總結(jié)

以上是生活随笔為你收集整理的内存分配与数据格式化(malloc与new)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。