新手做自己的網(wǎng)站教程google廣告
1.初步了解內(nèi)存中各個區(qū)間存儲的數(shù)據(jù)特征
1.棧區(qū):存儲一些局部變量、函數(shù)參數(shù)、返回值等,跟函數(shù)棧振有關(guān),出了作用域,生命周期結(jié)束。
2.堆區(qū):用于動態(tài)開辟空間,如果不主動銷毀空間,則程序運(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語言實(shí)現(xiàn)內(nèi)存管理
2.1malloc
在堆上開一快符合你預(yù)期大小的一塊空間,并且返回指向該地址空間的指針
void* malloc (size_t size);
size:開多大的空間,單位是字節(jié)
2.2realloc
如果malloc開辟出來的空間開少了,realloc可以在堆上重新開一塊符合你預(yù)期大小的空間,并返回指向該空間的指針
void*?realloc (void * ptr,size_t size);
ptr:初始空間的地址
size:將空間開辟到多大
?2.3calloc
用于對開辟的空間進(jìn)行初始化,calloc會將開辟的空間中每個元素初始化為0
void*?realloc (size_t num,size_t size);
num:分配的元素數(shù)量
size:每個元素的大小
3.c++實(shí)現(xiàn)內(nèi)存管理
3.1 new/delete new []/delete []
在c++中,有兩對操作符new/delete、new []/delete [],他們的作用是負(fù)責(zé)開空間和釋放空間!!!
new作用跟malloc類似,delete作用跟free類似
new和delete在面對自定義類型時會去調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
new =先申請對象空間?再調(diào)用構(gòu)造函數(shù)
delete =?先調(diào)用析構(gòu)函數(shù)?再釋放對象空間
3.1.1內(nèi)置類型
當(dāng)需要開一個整形的空間時。
int main()
{ //mallocint* p1 = (int*)malloc(sizeof(int));//new開空間用法跟malloc不同,但是作用相同,都是負(fù)責(zé)開空間!!!int* p2 = new int;//freefree(p1);//deletedelete(p2);return 0;
}
當(dāng)需要開多個空間時?例如開10個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在面對自定義類型時會去調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
new =先開空間?再調(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先開空間 再去調(diào)用構(gòu)造函數(shù)delete(p2);//delete先調(diào)用析構(gòu)函數(shù),再去釋放空間return 0;
}
如果需要開10個Stack類型的空間?用new[]?和 delete[]
int main()
{Stack* p2 = new Stack[10];//new先開空間 再去調(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?這兩個全局函數(shù)
在c++中,有這樣兩個全局函數(shù),他們的作用跟malloc、free類似,都是負(fù)責(zé)開空間和釋放空間!!!
注意:operator new /?operator?delete?不是new/delete的重載,而是兩個全局函數(shù)!!!
我們知道m(xù)alloc申請空間失敗的時候,會返回空。而operator new申請空間失敗的時候則會拋異常。我們可以理解為operator是封裝的malloc。
也就是說operator?new?和mclloc除了申請空間失敗的處理方法不同,其他的用法以及功能是相同的!!!
operator?delete?可以理解為跟operator?new對應(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.申請對象空間 + 2.調(diào)用構(gòu)造
delete = 1.調(diào)用析構(gòu) + 2.釋放對象空間
在底層原理上,new的第一步申請對象空間底層就是調(diào)用operator new函數(shù),
operator的第二步釋放對象空間底層就是調(diào)用operator?operator函數(shù).
也就是說下面兩段不同的代碼,起到的作用都是相同的?
int main()
{Stack* p1 = new Stack;delete (p1);//等價于newStack* p2 = (Stack*)operator new (sizeof(Stack));//定位new顯示調(diào)用構(gòu)造函數(shù)new(p2)Stack;//等價于deletep2->~Stack();operator delete(p2);return 0;
}
我們到匯編語言的角度證明一下