C/C++內存管理

請先閱讀下邊一段代碼,並思考所附的練習題:

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);
}
1. 選擇題:
 選項: A.棧 B.堆 C.數據段 D.代碼段
 globalVar在哪裏?____ staticGlobalVar在哪裏?____
 staticVar在哪裏?____ localVar在哪裏?____
 num1 在哪裏?____
 
 char2在哪裏?____ *char2在哪裏?___
 pChar3在哪裏?____ *pChar3在哪裏?____
 ptr1在哪裏?____ *ptr1在哪裏?____
答案:CCCAA  AAADAD
 sizeof(num1) = ____; 
 sizeof(char2) = ____; strlen(char2) = ____;
 sizeof(pChar3) = ____; strlen(pChar3) = ____;
 sizeof(ptr1) = ____;
 答案:4054432位)/864位) 、  4432位)/864位) 

【說明】

  1. 棧又叫堆棧,非靜態局部變量/函數參數/返回值等等,棧是向下增長的。
  2. 內存映射段是高效的I/O映射方式,用於裝載一個共享的動態內存庫。用戶可使用系統接口創建共享共享內存,做進程間通信。
  3. 堆用於程序運行時動態內存分配,堆是可以上增長的。
  4. 數據段–存儲全局數據和靜態數據。
  5. 代碼段–可執行的代碼/只讀常量。
    C語言中內存管理,請看以下示例代碼作爲複習:
void Test ()
{
 int* p1 = (int*) malloc(sizeof(int));
 free(p1);
 
 // 1.malloc/calloc/realloc的區別是什麼?
 int* p2 = (int*)calloc(4, sizeof (int));
 int* p3 = (int*)realloc(p2, sizeof(int)*10);
 
 // 這裏需要free(p2)嗎?
 free(p3 );
}

C++中內存管理: C語言內存管理方式在C++中可以繼續使用,但有些地方就無能爲力而且使用起來比較麻煩,因此C++又提出了自己的內存管理方式:通過new和delete操作符進行動態內存管理。

new和delete操作內置類型:

void Test()
{
 // 動態申請一個int類型的空間
 int* ptr4 = new int;
 
 // 動態申請一個int類型的空間並初始化爲10
 int* ptr5 = new int(10);
 
 // 動態申請3個int類型的空間
 int* ptr6 = new int[3];
 
 delete ptr4;
 delete ptr5;
 delete[] ptr6;
}

在這裏插入圖片描述
注意:申請和釋放單個元素的空間,使用new和delete操作符,申請和釋放連續的空間,使用 new[] 和 delete[];

new和delete操作自定義類型:

class Test
{
public:
 Test()
 : _data(0)
 {
 cout<<"Test():"<<this<<endl;
 }
 ~Test()
 {
 cout<<"~Test():"<<this<<endl;
 }
 
private:
 int _data;
};
void Test2()
{
 // 申請單個Test類型的空間
 Test* p1 = (Test*)malloc(sizeof(Test));
 free(p1);
 
 // 申請10個Test類型的空間
 Test* p2 = (Test*)malloc(sizoef(Test) * 10);
 free(p2);
}

void Test2()
{
 // 申請單個Test類型的對象
 Test* p1 = new Test;
 delete p1;
 
 // 申請10個Test類型的對象
 Test* p2 = new Test[10];
 delete[] p2;
}

注意:在申請自定義類型的空間時,new會調用構造函數,delete會調用析構函數,而malloc與free不會

new和delete的實現原理:
1.內置類型
如果申請的是內置類型的空間,new和malloc,delete和free基本類似,不同的地方是:new/delete申請和釋放的是單個元素的空間,new[]和delete[]申請的是連續空間,而且new在申請空間失敗時會拋異常,malloc會返回NULL。
2. 自定義類型

new的原理:
調用operator new函數申請空間
在申請的空間上執行構造函數,完成對象的構造

delete的原理
在空間上執行析構函數,完成對象中資源的清理工作
調用operator delete函數釋放對象的空間

new T[N]的原理
調用operator new[]函數,在operator new[]中實際調用operator new函數完成N個對象空間的申請,在申請的空間上執行N次構造函數。

delete[]的原理
在釋放的對象空間上執行N次析構函數,完成N個對象中資源的清理
調用operator delete[]釋放空間,實際在operator delete[]中調用operator delete來釋放空間

總結:

malloc/free和new/delete的區別

malloc/free和new/delete的共同點是:都是從堆上申請空間,並且需要用戶手動釋放。
不同點:

  1. malloc和free是函數,new和delete是操作符
  2. malloc申請的空間不會初始化,new可以初始化
  3. malloc申請空間時,需要手動計算空間大小並傳遞,new只需在其後跟上空間的類型即可
  4. malloc的返回值爲void*, 在使用時必須強轉,new不需要,因爲new後跟的是空間的類型
  5. malloc申請空間失敗時,返回的是NULL,因此使用時必須判空,new不需要,但是new需
  6. 申請自定義類型對象時,malloc/free只會開闢空間,不會調用構造函數與析構函數,而ne後會調用構造函數完成對象的初始化,delete在釋放空間前會調用析構函數完成空間中資源
  7. new/delete比malloc和free的效率稍微低點,因爲new/delete的底層封裝了malloc/free
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章