很好地理解動(dòng)態(tài)內(nèi)存到底如何在 C++ 中發(fā)揮作用是成為一個(gè)好的 C++ 程序員所必需的。 C++ 程序中的內(nèi)存分為兩個(gè)部分:
很多時(shí)候,你事先不知道你在一個(gè)定義的變量中需要多少內(nèi)存來存儲(chǔ)特定的信息以及在程序運(yùn)行時(shí)所需內(nèi)存的大小。
你可以在運(yùn)行時(shí)為指定類型的變量分配堆內(nèi)存,并且可以使用 C++ 中特殊操作符返回分配空間的地址。這個(gè)操作符被稱為 new 操作符。
如果你不再需要?jiǎng)討B(tài)分配內(nèi)存了,你可以使用 delete 操作符來釋放之前用 new 操作符分配的內(nèi)存。
下面是使用 new 操作符為任意數(shù)據(jù)類型動(dòng)態(tài)地分配內(nèi)存的通用的語法。
new data-type;
這里, data-type 可以是任何內(nèi)置數(shù)據(jù)類型,包括數(shù)組或任何用戶定義的數(shù)據(jù)類型包括類或結(jié)構(gòu)。讓我們先看看內(nèi)置的數(shù)據(jù)類型。例如,我們可以定義一個(gè) double 類型的指針然后在程序執(zhí)行時(shí)請(qǐng)求分配內(nèi)存。我們可以使用 new 操作符來完成它,程序語句如下:
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
如果自由存儲(chǔ)區(qū)都已經(jīng)被占用,內(nèi)存可能就不能被成功分配。因此檢查 new 操作符是否返回空指針是一種很好的做法,并且要采取適當(dāng)?shù)拇胧┤缦拢?/p>
double* pvalue = NULL;
if( !(pvalue = new double ))
{
cout << "Error: out of memory." <<endl;
exit(1);
}
C 語言中的 malloc() 函數(shù)在C++中仍然存在,但是建議避免使用 malloc()
函數(shù)。相對(duì)于 malloc()
函數(shù) new 操作符的主要優(yōu)勢(shì)是 new 操作符不僅分配內(nèi)存,它還可以構(gòu)造對(duì)象,而這正是 C++ 的主要目的?! ?/p>
在任何時(shí)候,當(dāng)你覺得一個(gè)變量已經(jīng)不再需要?jiǎng)討B(tài)分配,你可以用 delete 操作符來釋放它在自由存儲(chǔ)區(qū)所占用的內(nèi)存,如下:
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;
}
如果我們編譯和運(yùn)行上面的代碼,這將產(chǎn)生以下結(jié)果:
Value of pvalue : 29495
考慮到你想要為字符數(shù)組分配內(nèi)存,即 20 個(gè)字符的字符串。使用與上面相同的語法我們可以動(dòng)態(tài)地分配內(nèi)存,如下所示。
char* pvalue = NULL; // Pointer initialized with null
pvalue = new char[20]; // Request memory for the variable
應(yīng)該像這樣刪除我們剛剛創(chuàng)建的數(shù)組聲明:
delete [] pvalue;// Delete array pointed to by pvalue
學(xué)習(xí)過 new 操作符的類似通用語法,你可以為一個(gè)多維數(shù)組分配內(nèi)存如下:
double** pvalue = NULL; // Pointer initialized with null
pvalue 、= new double [3][4]; // Allocate memory for a 3x4 array
然而,釋放多維數(shù)組內(nèi)存的語法仍然同上:
delete [] pvalue;// Delete array pointed to by pvalue
對(duì)象與簡(jiǎn)單的數(shù)據(jù)類型并無不同。例如,考慮下面的代碼,我們將使用一個(gè)對(duì)象數(shù)組來解釋這個(gè)概念:
#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;
}
如果你為四個(gè) Box 對(duì)象數(shù)組分配內(nèi)存,一個(gè)簡(jiǎn)單的構(gòu)造函數(shù)將被調(diào)用四次,同樣的刪除這些對(duì)象時(shí),析構(gòu)函數(shù)也被調(diào)用相同的次數(shù)。
如果我們編譯和運(yùn)行上面的代碼,這將產(chǎn)生以下結(jié)果:
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!