
- C++ 基礎
- C++ 首頁
- C++ 概述
- C++ 環境設定
- C++ 基本語法
- C++ 註釋
- C++ Hello World
- C++ 省略名稱空間
- C++ 常量/字面量
- C++ 關鍵字
- C++ 識別符號
- C++ 資料型別
- C++ 數值資料型別
- C++ 字元資料型別
- C++ 布林資料型別
- C++ 變數型別
- C++ 變數作用域
- C++ 多個變數
- C++ 基本輸入/輸出
- C++ 修飾符型別
- C++ 儲存類
- C++ 運算子
- C++ 數字
- C++ 列舉
- C++ 引用
- C++ 日期和時間
- C++ 控制語句
- C++ 決策
- C++ if 語句
- C++ if else 語句
- C++ 巢狀 if 語句
- C++ switch 語句
- C++ 巢狀 switch 語句
- C++ 迴圈型別
- C++ while 迴圈
- C++ for 迴圈
- C++ do while 迴圈
- C++ foreach 迴圈
- C++ 巢狀迴圈
- C++ break 語句
- C++ continue 語句
- C++ goto 語句
- C++ 建構函式
- C++ 建構函式和解構函式
- C++ 複製建構函式
C++ 動態記憶體
深入理解 C++ 中動態記憶體的工作原理對於成為一名優秀的 C++ 程式設計師至關重要。C++ 程式中的記憶體分為兩個部分:
棧 - 在函式內部宣告的所有變數都將從棧中佔用記憶體。
堆 - 這是程式的未使用記憶體,可以在程式執行時動態分配記憶體。
很多時候,您事先並不知道需要多少記憶體來儲存定義變數中的特定資訊,並且所需記憶體的大小可以在執行時確定。
您可以使用 C++ 中的一個特殊運算子在執行時在堆中為給定型別的變數分配記憶體,該運算子返回已分配空間的地址。此運算子稱為new運算子。
如果您不再需要動態分配的記憶體,可以使用delete運算子,它將釋放之前由 new 運算子分配的記憶體。
new 和 delete 運算子
以下是一般語法,用於使用new運算子為任何資料型別動態分配記憶體。
new data-type;
這裡,data-type可以是任何內建資料型別,包括陣列或任何使用者定義的資料型別,包括類或結構體。讓我們從內建資料型別開始。例如,我們可以定義一個指向 double 型別的指標,然後請求在執行時分配記憶體。我們可以使用以下語句使用new運算子來做到這一點:
double* pvalue = NULL; // Pointer initialized with null pvalue = new double; // Request memory for the variable
如果空閒儲存已用完,則記憶體可能無法成功分配。因此,最好檢查 new 運算子是否返回 NULL 指標並採取適當的操作,如下所示:
double* pvalue = NULL; if( !(pvalue = new double )) { cout << "Error: out of memory." <<endl; exit(1); }
來自 C 的malloc()函式仍然存在於 C++ 中,但建議避免使用 malloc() 函式。new 相對於 malloc() 的主要優勢在於,new 不僅分配記憶體,還構造物件,這是 C++ 的主要目的。
在任何時候,當您認為一個已動態分配的變數不再需要時,您可以使用‘delete’運算子釋放它在空閒儲存中佔用的記憶體,如下所示:
delete pvalue; // Release memory pointed to by pvalue
讓我們將上述概念組合成以下示例,以展示‘new’和‘delete’是如何工作的:
#include <iostream> using namespace std; int main () { double* pvalue = NULL; // Pointer initialized with null pvalue = new double; // Request memory for the variable *pvalue = 29494.99; // Store value at allocated address cout << "Value of pvalue : " << *pvalue << endl; delete pvalue; // free up the memory. return 0; }
如果我們編譯並執行上述程式碼,這將產生以下結果:
Value of pvalue : 29495
陣列的動態記憶體分配
假設您想為一個字元陣列(即 20 個字元的字串)分配記憶體。使用與上面我們使用的相同的語法,我們可以動態分配記憶體,如下所示。
char* pvalue = NULL; // Pointer initialized with null pvalue = new char[20]; // Request memory for the variable
要刪除我們剛剛建立的陣列,該語句將如下所示:
delete [] pvalue; // Delete array pointed to by pvalue
遵循 new 運算子的類似通用語法,您可以為多維陣列分配記憶體,如下所示:
double** pvalue = NULL; // Pointer initialized with null pvalue = new double [3][4]; // Allocate memory for a 3x4 array
但是,釋放多維陣列記憶體的語法仍然與上面相同:
delete [] pvalue; // Delete array pointed to by pvalue
物件的動態記憶體分配
物件與簡單資料型別沒有什麼不同。例如,考慮以下程式碼,我們將使用物件陣列來闡明這個概念:
#include <iostream> using namespace std; class Box { public: Box() { cout << "Constructor called!" <<endl; } ~Box() { cout << "Destructor called!" <<endl; } }; int main() { Box* myBoxArray = new Box[4]; delete [] myBoxArray; // Delete array return 0; }
如果您要分配四個 Box 物件的陣列,則 Simple 建構函式將被呼叫四次,類似地,在刪除這些物件時,解構函式也將被呼叫相同次數。
如果我們編譯並執行上述程式碼,這將產生以下結果:
Constructor called! Constructor called! Constructor called! Constructor called! Destructor called! Destructor called! Destructor called! Destructor called!