東莞公司網(wǎng)站建設(shè)seo推廣需要多少錢
1.初步了解內(nèi)存中各個(gè)區(qū)間存儲(chǔ)的數(shù)據(jù)特征
1.棧區(qū):存儲(chǔ)一些局部變量、函數(shù)參數(shù)、返回值等,跟函數(shù)棧振有關(guān),出了作用域,生命周期結(jié)束。
2.堆區(qū):用于動(dòng)態(tài)開(kāi)辟空間,如果不主動(dòng)銷毀空間,則程序運(yùn)行結(jié)束,生命周期結(jié)束。
3.數(shù)據(jù)段(靜態(tài)區(qū)):static修飾的靜態(tài)變量和全局變量,程序運(yùn)行結(jié)束,生命周期結(jié)束。
4.代碼段(常量區(qū)):可執(zhí)行的代碼和常量。
練習(xí)
int globalVar = 1; static int staticGlobalVar = 1; void Test() { static int staticVar = 1; int localVar = 1; int num1[10] = { 1, 2, 3, 4 }; char char2[] = "abcd"; const char* pChar3 = "abcd"; int* ptr1 = (int*)malloc(sizeof(int) * 4); int* ptr2 = (int*)calloc(4, sizeof(int)); int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4); free(ptr1); free(ptr3); }
選項(xiàng) : A . 棧 ? B . 堆 ? C . 數(shù)據(jù)段 ( 靜態(tài)區(qū) ) ? D . 代碼段 ( 常量區(qū) )globalVar 在哪里? __1__ ? staticGlobalVar 在哪里? __2__staticVar 在哪里? __3__ ? localVar 在哪里? __4__num1 在哪里? __5__char2 在哪里? __6__ ? * char2 在哪里? __7_pChar3 在哪里? __8__ ? ? ? * pChar3 在哪里? __9__ptr1 在哪里? __10__ ? ? ? ? * ptr1 在哪里? __11__
1.C? ? ? ?2.C? ? ? ?3.C? ? ? ? 4. A? ? ? ?5.A? ? ? ?6.A? ? ? ? 7. A? ? ? ?8.A? ? ? ? 9.D? ? ? ? 10.A? ? ? ? 11.B

結(jié)合上圖可以得知,cha2其本身存放在棧區(qū),指針指向棧區(qū)中數(shù)組首元素的地址,再將靜態(tài)區(qū)中"abcd"賦值給數(shù)組,所以*char指向的元素在棧區(qū)!!!pChar3其本身存放在棧區(qū),指向靜態(tài)區(qū)中存放"abcd"字符串的首地址!!!
2.c語(yǔ)言實(shí)現(xiàn)內(nèi)存管理
2.1malloc
在堆上開(kāi)一快符合你預(yù)期大小的一塊空間,并且返回指向該地址空間的指針
void* malloc (size_t size);
size:開(kāi)多大的空間,單位是字節(jié)
2.2realloc
如果malloc開(kāi)辟出來(lái)的空間開(kāi)少了,realloc可以在堆上重新開(kāi)一塊符合你預(yù)期大小的空間,并返回指向該空間的指針
void*?realloc (void * ptr,size_t size);
ptr:初始空間的地址
size:將空間開(kāi)辟到多大
?2.3calloc
用于對(duì)開(kāi)辟的空間進(jìn)行初始化,calloc會(huì)將開(kāi)辟的空間中每個(gè)元素初始化為0
void*?realloc (size_t num,size_t size);
num:分配的元素?cái)?shù)量
size:每個(gè)元素的大小
3.c++實(shí)現(xiàn)內(nèi)存管理
3.1 new/delete new []/delete []
在c++中,有兩對(duì)操作符new/delete、new []/delete [],他們的作用是負(fù)責(zé)開(kāi)空間和釋放空間!!!
new作用跟malloc類似,delete作用跟free類似
new和delete在面對(duì)自定義類型時(shí)會(huì)去調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
new =先申請(qǐng)對(duì)象空間?再調(diào)用構(gòu)造函數(shù)
delete =?先調(diào)用析構(gòu)函數(shù)?再釋放對(duì)象空間
3.1.1內(nèi)置類型
當(dāng)需要開(kāi)一個(gè)整形的空間時(shí)。
int main()
{ //mallocint* p1 = (int*)malloc(sizeof(int));//new開(kāi)空間用法跟malloc不同,但是作用相同,都是負(fù)責(zé)開(kāi)空間!!!int* p2 = new int;//freefree(p1);//deletedelete(p2);return 0;
}
當(dāng)需要開(kāi)多個(gè)空間時(shí)?例如開(kāi)10個(gè)int類型的空間 需要加上[]
int main()
{int* p1 = (int*)malloc(sizeof(int)*10);int* p2 = new int[10];free(p1);delete[](p2);return 0;
}
3.1.2自定義類型
new和delete在面對(duì)自定義類型時(shí)會(huì)去調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
new =先開(kāi)空間?再調(diào)用構(gòu)造函數(shù)
delete =?先調(diào)用析構(gòu)函數(shù)?再釋放空間
class Stack
{
public:Stack(int capacity = 4){_a = new int[capacity];int _top = 0;int _capacity = capacity;}~Stack(){delete (_a);_a = nullptr;_top = 0;_capacity = 0;}
private:int* _a;int _top;int _capacity;
};
int main()
{Stack* p2 = new Stack;//new先開(kāi)空間 再去調(diào)用構(gòu)造函數(shù)delete(p2);//delete先調(diào)用析構(gòu)函數(shù),再去釋放空間return 0;
}
如果需要開(kāi)10個(gè)Stack類型的空間?用new[]?和 delete[]
int main()
{Stack* p2 = new Stack[10];//new先開(kāi)空間 再去調(diào)用構(gòu)造函數(shù)delete[](p2);//delete先調(diào)用析構(gòu)函數(shù),再去釋放空間return 0;
}
?3.2new/delete底層實(shí)現(xiàn)原理
3.2.1?全局函數(shù) operator new/operator delete
要知道原理,我們就得先知道operatot new / operator delete?這兩個(gè)全局函數(shù)
在c++中,有這樣兩個(gè)全局函數(shù),他們的作用跟malloc、free類似,都是負(fù)責(zé)開(kāi)空間和釋放空間!!!
注意:operator new /?operator?delete?不是new/delete的重載,而是兩個(gè)全局函數(shù)!!!
我們知道m(xù)alloc申請(qǐng)空間失敗的時(shí)候,會(huì)返回空。而operator new申請(qǐng)空間失敗的時(shí)候則會(huì)拋異常。我們可以理解為operator是封裝的malloc。
也就是說(shuō)operator?new?和mclloc除了申請(qǐng)空間失敗的處理方法不同,其他的用法以及功能是相同的!!!
operator?delete?可以理解為跟operator?new對(duì)應(yīng),其用法和功能跟free完全一樣!!!
int main()
{Stack* p1 = (Stack*)malloc(sizeof(Stack));free(p1);//operator new底層用的是mallocStack* p2 = (Stack*)operator new (sizeof(Stack));//operator delete底層用是freeoperator delete(p2);return 0;
}
3.2.2 new/delete?和?operator?new/operator delete的關(guān)系
new = 1.申請(qǐng)對(duì)象空間 + 2.調(diào)用構(gòu)造
delete = 1.調(diào)用析構(gòu) + 2.釋放對(duì)象空間
在底層原理上,new的第一步申請(qǐng)對(duì)象空間底層就是調(diào)用operator new函數(shù),
operator的第二步釋放對(duì)象空間底層就是調(diào)用operator?operator函數(shù).
也就是說(shuō)下面兩段不同的代碼,起到的作用都是相同的?
int main()
{Stack* p1 = new Stack;delete (p1);//等價(jià)于newStack* p2 = (Stack*)operator new (sizeof(Stack));//定位new顯示調(diào)用構(gòu)造函數(shù)new(p2)Stack;//等價(jià)于deletep2->~Stack();operator delete(p2);return 0;
}
我們到匯編語(yǔ)言的角度證明一下