文章目錄
- 前言
- `new` 運算
- 創建一個資料物件
- 創建多個資料物件----即陣列
- ★注意
- `delete` 運算
- 面試題
- 一、malloc/free和new/delete的區別
- 二、如何一次在堆上申請4G的記憶體?
前言
- 對于型別相同的的大量資料,我們可以用陣列來存盤,陣列是一種靜態記憶體分配方法,其長度是固定的,由陣列定義陳述句確定,由編譯系統予以分配,
在程式的運行程序中,有時我們很難事先確定需要多少陣列元素,只能按照預先估算的最大數量進行定義,這樣會造成一大部分記憶體的浪費,而且一旦超過預先定義的最大個數,陣列就會越界,造成程式例外,
動態記憶體分配技術可以保證程式在運行程序中根據實際需要申請適量的記憶體,使用結束后還可以釋放并回傳給系統,C++通過new運算子和delete運算子實作動態記憶體分配,
如需查看C語言動態管理,請點擊查看我往期博客,
new 運算
new運算的作用是按照指定的型別和大小動態地去分配記憶體,基本語法如下:
指標變數 = new 型別名 (初值串列);
其中:
- 資料型別可以是內置的資料型別,也可以是用戶自定義的復雜資料型別,
new運算子在堆(記憶體)中創建一個由型別名指定型別的物件,如果創建成功,回傳物件的地址,否則回傳空指標nullptr,- 初值串列給初被創建物件的初始值,
- 由于回傳的是地址,所以要用實作定義好的一個相同型別的指標變數去接收這個地址,
例①:
創建一個資料物件
int* pi = new int(10); //pi指向一個初始值為10的 int 型的物件
//也可以使用分開定義,如下
int* pj;
pj = new int(10);
首先我們定義了一個整形指標pi,然后使用new運算子去申請記憶體空間來創建一個初始值為10的int型資料物件,最后回傳創建好的資料物件的地址存入到pi當中,
創建多個資料物件----即陣列
當然
new運算子也可以像c語言當中的malloc和calloc一樣創建多個同型別的物件,new運算子創建動態陣列時,需要給出陣列的結構說明,其語法形式如下:
指標變數 = new 型別名 [下標運算式];
其中:
- 下標運算式與陣列初始化時的常量運算式不同,可以是變數運算式,
用new運算子申請記憶體失敗時回傳nullptr,申請一個動態陣列往往需要一個較大的空間,因此在程式中需要使用new的回傳值進行判斷,看是否申請記憶體成功,
例②:
int* pa;
pa = new int[5]; //pa指向5個未初始化的int型資料物件的首地址
//如果想要將pa在創建時就初始化好應改為如下代碼
pa = new int[5]{ 1,2,3,4}; //此時第一個int型的物件的值就為1,同理后面的物件依次是{}中給出的值
//當{}中給初的數值的個數小于創建的物件個數時,會將其值默認初始化為0
//也可以使用一條陳述句定義
int*pa=new int[5];
//如果像將其初始化則像上述代碼一樣修改即可
結果如下:

★注意
(1)用
new運算子申請分配的記憶體空間必須用delete釋放,
(2)delete作用的指標必須是由new分配記憶體空間的首地址,
(3)對于一個已分配記憶體的指標,只能用delete釋放一次,
(4)new和delete運算實作了堆空間的動態分配,它在帶來方便的同時也潛伏了可能的 隱患:使用new進行記憶體分配之后,忘記了使delete運算進行記憶體回收,即“記憶體泄露”,如 果程式長時間運行,則有可能因記憶體耗盡而使系統崩潰,所以對new和delete要養成配對使用的良好習慣,
delete 運算
當程式不需要由new分配的記憶體空間時,可以用
delete釋放這些空間,其語法格式如下:
delete 指標變數名;
如果洗掉的是動態陣列,則語法格式如下:
delete[]指標變數名;
其中:
- 括號[]表示用delete釋放為多少個物件分配的地址,[]中不需要說明物件的個數,
- 不管建立的動態陣列是多少維,釋放的格式都是一樣的,
對于例①、②分配的空間,釋放陳述句如例③一樣:
例③:
delete pi;
delete []pa;
例④:
class Obj
{
public:
Obj(void); // 無引數的建構式
Obj(int x); // 帶一個引數的建構式
}
void Test(void)
{
Obj *a = new Obj;
Obj *b = new Obj(1); // 初值為 1
delete a;
delete b;
}
如果用 new 創建物件陣列,那么只能使用物件的無引數建構式,例如
Obj *objects = new Obj[100]; // 創建 100 個動態物件
不能寫成
Obj *objects = new Obj[100] (1);// 創建 100 個動態物件的同時賦初值 1
在用 delete 釋放物件陣列時,留意不要丟了符號‘[]’,例如
delete []objects; // 正確的用法
delete objects; // 錯誤的用法
后者相當于 delete objects[0],漏掉了另外 99 個物件,
面試題
一、malloc/free和new/delete的區別
malloc和free是函式,new和delete是運算子,malloc申請的空間不會初始化,new可以初始化,malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上空間的型別即可,malloc的回傳值為void*, 在使用時必須強制型別轉換,new不需要,因為new后跟的是空間的型別,malloc申請空間失敗時,回傳的是NULL,因此使用時必須判空,new不需要,但是new需要捕獲例外,- 申請自定義型別物件時,
malloc/free只會開辟空間,不會呼叫建構式與解構式,而new在申請空間后會呼叫建構式完成物件的初始化,delete在釋放空間前會呼叫解構式完成空間中資源的清理,
二、如何一次在堆上申請4G的記憶體?
在32位平臺下malloc與new最大能申請2GB左右的記憶體,
只需把我們的環境改成64位平臺下即可申請成功4GB的記憶體,
在64位平臺下最大能申請的記憶體大小約為160億GB左右,

END...
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/286422.html
標籤:其他
