C++動態內存
了解動態內存在C++中如何工作是成為一個很好的C++程序員必不可少的。C++程序存儲器分為兩個部分:
-
棧: 在函數內部聲明的所有變量都將占用棧內存。
-
堆: 這是程序未使用的存儲器,可以用於當程序運行時動態分配的存儲器。
很多時候,不知道提前知道需要多少內存,需要存儲的特定信息的定義的變量和所需內存的大小可以在運行時才確定。
可以在運行時在堆內分配存儲器給定類型的使用特殊的運算符在C++中返回所分配的空間變量的地址。這種運算符被稱為new運算符。
如果不需要動態分配的內存,可以使用delete運算符,刪除分配內存之前由new運算符分配。
new和delete運算符:
有以下通用語法使用new運算符來動態分配內存任何的數據類型。
new data-type;
這裡,數據類型可以是包括數組或定義的數據類型包括類或結構的任何用戶的任何內置數據類型。讓我們從內置的數據類型。例如,我們可以定義一個指針,指向double類型,然後請求的內存在執行時進行分配。我們可以使用new運算符使用下麵的語句做到這一點:
double* pvalue = NULL; // Yiibaier initialized with null pvalue = new double; // Request memory for the variable
存儲器可能冇有成功地分配,如果自由存儲區已被用完。所以這是很好的做法,檢查是否有新的操作符返回NULL指針,並采取以下適當的操作:
double* pvalue = NULL; if( !(pvalue = new double )) { cout << "Error: out of memory." <<endl; exit(1); }
malloc()函數是在C語言中,但它仍然存在在C++中,但建議避免使用malloc()函數。new比malloc()函數的主要優點是,new不隻是分配內存,它還為C++構造創建對象。
在任何時候,當已經動態分配,不再被需要的變量,可以使用delete操作符釋放它占用的內存如下:
delete pvalue; // Release memory yiibaied to by pvalue
讓我們把上述概念,並形成以下例子來說明如何利用new 和 delete 來工作:
#include <iostream> using namespace std; int main () { double* pvalue = NULL; // Yiibaier 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; // Yiibaier initialized with null pvalue = new char[20]; // Request memory for the variable
要刪除我們剛才創建的聲明數組,是這樣的:
delete [] pvalue; // Delete array yiibaied to by pvalue
下麵的new操作符的類似通用語法,可以分配一個多維數組,如下所示:
double** pvalue = NULL; // Yiibaier initialized with null pvalue = new double [3][4]; // Allocate memory for a 3x4 array
但是,用於多維數組的存儲器釋放語法將仍然保持與上述相同的:
delete [] pvalue; // Delete array yiibaied 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對象的數組,簡單的構造將被調用4次,同樣,同時刪除這些對象,析構也將被調用次數(4次)相同。
如果我們編譯並運行上麵的代碼,這會產生以下結果:
Constructor called! Constructor called! Constructor called! Constructor called! Destructor called! Destructor called! Destructor called! Destructor called!