一、C語言動態內存管理方式
在C語言中,動態內存管理的接口有malloc/calloc/realloc,那麼三者之間有什麼區別呢?
簡單來說就是malloc是動態開闢空間;calloc是開闢空間的同時按字節進行初始化爲0,並且可以擴容,須知道要擴容到多大;realloc是對當前空間進行增容,對已有空間進行操作,空間足夠大時原地擴容,否則另外擴容。
詳細可見【C語言】malloc,calloc,realloc的區別
二、C++動態內存管理方式
C語言內存管理方式在C++中可以繼續使用,但有些地方就無能爲力而且使用起來比較麻煩,因此C++又提出了自己的內存管理方式:通過new和delete操作符進行動態內存管理。
new/delete操作內置類型
先來看段代碼:
void Test()
{
// 動態申請一個int類型的空間
int* ptr4 = new int;
// 動態申請一個int類型的空間並初始化爲10
int* ptr5 = new int(10);
// 動態申請10個int類型的空間
int* ptr6 = new int[10];
delete ptr4;
delete ptr5;
delete[] ptr6;
}
【總結】:申請和釋放單個元素的空間,使用new和delete操作符,申請和釋放連續的空間,使用new[]和delete[]
new/delete操作自定義類型
#include <iostream>
using namespace std;
class Date
{
public:
Date(int year=1990, int month=1, int day=1)
:_year(year)
, _month(month)
, _day(day)
{}
~Date()
{
cout << "~Date()" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
//基本類型(內置類型)
int* p1 = new int;//C++開闢
int* p2 = (int*)malloc(sizeof(int));//C語言開闢
delete p1;
free(p2);
//自定義類型
Date* p3 = new Date;//開空間+初始化
Date* p3 = new Date(2019,3,2);//開空間+初始化
Date* p4 = (Date*)malloc(sizeof(Date));//開空間
delete p3;//析構(清理)+釋放空間
delete p4;//析構(清理)+釋放空間
free(p4);//釋放空間
system("pause");
return 0;
}
【總結】:在申請自定義類型的空間時,new會調用構造函數,delete會調用析構函數,而malloc與free不會。一定要匹配使用,不要混用!!!
三、operator new與operator delete函數
new和delete是用戶進行動態內存申請和釋放的操作符,operator new 和operator delete是系統提供的全局函數,new在底層調用operator new全局函數來申請空間,delete在底層通過operator delete全局函數來釋放空間。用法如下:
int* p1 = (int*)operator new(sizeof(int));
operator delete(p1);
我們可以看出operator new 、operator delete 與 malloc 、free 的用法完全一樣,那麼他們之間的區別是什麼呢?
它們主要在於處理錯誤的方式有區別:operator new失敗拋異常,而malloc失敗返回NULL(0)
malloc/free和new/delete的區別
malloc/free和new/delete的共同點是:都是從堆上申請空間,並且需要用戶手動釋放。不同的地方是:
- malloc和free是函數,new和delete是操作符
- malloc申請的空間不會初始化,new可以初始化
- malloc申請空間時,需要手動計算空間大小並傳遞,new只需在其後跟上空間的類型即可
- malloc的返回值爲void*, 在使用時必須強轉,new不需要,因爲new後跟的是空間的類型
- malloc申請空間失敗時,返回的是NULL,因此使用時必須判空,new不需要,但是new需要捕獲異常
- 申請自定義類型對象時,malloc/free只會開闢空間,不會調用構造函數與析構函數,而new在申請空間後會調用構造函數完成對象的初始化,delete在釋放空間前會調用析構函數完成空間中資源的清理
- new/delete比malloc和free的效率稍微低點,因爲new/delete的底層封裝了malloc/free