
目錄
一,C/C++記憶體分布
二,C語言中動態記憶體管理方式
三,C++記憶體管理方式
四,operator new與operator delete函式
五,常見面試題
malloc/free和new/delete的區別:
記憶體泄露:
如何預防記憶體泄露:
一,C/C++記憶體分布

1,這幾個區域,堆是很大的
2,從圖中看,堆疊和堆差不多,實際堆疊很小,一般只有8M(LINUX下),所以遞回呼叫深度太深,會導致堆疊溢位
3,資料段和代碼段也不是很大,因為沒有多少資料
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";
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);
}
二,C語言中動態記憶體管理方式
malloc/calloc/realloc的區別?
calloc等價于malloc+memset(0) 開空間+初始化
realloc是對malloc或calloc的空間進行擴容
三,C++記憶體管理方式
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A()" << endl;
}
~A()
{
cout << "~A" << endl;
}
private:
int _a;
};
int main()
{
int* p1 = (int*)malloc(sizeof(int));
free(p1);
int* p2 = new int;
delete p2;
A* p3 = (A*)malloc(sizeof(A));
free(p3);
A*(p4) = new A;
delete p4;
return 0;
}
對于自定義型別,new/delete不僅僅會開空間/釋放空間,還會呼叫建構式和解構式,而malloc與free不會
四,operator new與operator delete函式
new T——》1:申請空間->operator new (如果申請空間失敗了,拋例外) 2:建構式
operator new就是對malloc封裝-》申請記憶體失敗了,拋例外
delete T——》1:呼叫T的解構式 2:operator delete(p)
class Stack
{
public:
Stack(int capacity = 4)
:_a(new int[capacity])
, _size(0)
, _capacity(capacity)
{
cout << "Stack(int capacity = 4)" << endl;
}
~Stack()
{
delete[] _a;
_size = _capacity = 0;
cout << "~Stack()" << endl;
}
};
int main()
{
Stack st;
Stack* ps = new Stack;
delete ps;
return 0;
}

五,常見面試題
malloc/free和new/delete的區別:
特點和用法:
1. malloc和free是函式,new和delete是運算子
2.malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上空間的型別即可
3. malloc的回傳值為void*, 在使用時必須強轉,new不需要,因為new后跟的是空間的型別
底層原理區別:
申請自定義型別物件時,malloc/free只會開辟空間,不會呼叫建構式與解構式,而new在申請空間后會呼叫建構式完成物件的初始化,delete在釋放空間前會呼叫解構式完成空間中資源的清理
處理錯誤的方式:
malloc申請空間失敗時,回傳的是NULL,因此使用時必須判空,new不需要,但是new需要捕獲例外
記憶體泄露:
int main()
{
char* p = new char[1024 * 1024 * 1024];
return 0;
}
上面程式存在記憶體泄露,一次泄露1G,但是多次泄露,對我們系統好像也沒什么影響
一個行程正常結束后,會把映射的記憶體都會釋放掉,所以上面的程式,我們沒有主動釋放,但是行程結束也釋放,那么記憶體泄露好像也沒啥事?因為行程正常結束,都會釋放,
其實不是:
第一:行程沒有正常結束,僵尸行程,就可能存在一些資源沒釋放,
第二:長期運行的服務器程式,長期運行,只有升級的時候才會停
記憶體泄露會導致可用記憶體越來越少,程式越來越慢,甚至掛掉——事故,
第三:物聯網設備:掃地機器人等,記憶體很小,也會經不起記憶體泄露的折騰,
C++需要主動釋放記憶體,java不需要主動釋放記憶體,java后臺有垃圾回收器,接管了記憶體釋放
如何預防記憶體泄露:
1,智能指標
2,記憶體泄露檢測工具:記憶體泄露檢測工具
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/348376.html
標籤:其他
上一篇:二叉樹的三種非遞回遍歷方式


