C++ 高级数据类型(四)—— 动态内存分配
到目前為止,我們的程序中我們只用了聲明變量、數(shù)組和其他對象(objects)所必需的內(nèi)存空間,這些內(nèi)存空間的大小都在程序執(zhí)行之前就已經(jīng)確定了。但如果我們需要內(nèi)存大小為一個變量,其數(shù)值只有在程序運行時 (runtime)才能確定,例如有些情況下我們需要根據(jù)用戶輸入來決定必需的內(nèi)存空間,那么我們該怎么辦呢?
答案是動態(tài)內(nèi)存分配(dynamic memory),為此C++ 集成了操作符new 和delete。
? 操作符?new?和?delete?是C++執(zhí)行指令。本節(jié)后面將會介紹這些操作符在C中的等價命令。
?
?
操作符new 和new[ ]
操作符new的存在是為了要求動態(tài)內(nèi)存。new 后面跟一個數(shù)據(jù)類型,并跟一對可選的方括號[ ]里面為要求的元素數(shù)。它返回一個指向內(nèi)存塊開始位置的指針。其形式為:
pointer = new type
或者
pointer = new type [elements]
第一個表達式用來給一個單元素的數(shù)據(jù)類型分配內(nèi)存。第二個表達式用來給一個數(shù)組分配內(nèi)存。
例如:
int * bobby;bobby = new int [5];
在這個例子里,操作系統(tǒng)分配了可存儲5個整型int元素的內(nèi)存空間,返回指向這塊空間開始位置的指針并將它賦給bobby。因此,現(xiàn)在bobby 指向一塊可存儲5個整型元素的合法的內(nèi)存空間,如下圖所示。
你可能會問我們剛才所作的給指針分配內(nèi)存空間與定義一個普通的數(shù)組有什么不同。最重要的不同是,數(shù)組的長度必須是一個常量,這就將它的大小在程序執(zhí)行之前的設計階段就被決定了。而采用動態(tài)內(nèi)存分配,數(shù)組的長度可以常量或變量,其值可以在程序執(zhí)行過程中再確定。
動態(tài)內(nèi)存分配通常由操作系統(tǒng)控制,在多任務的環(huán)境中,它可以被多個應用(applications)共享,因此內(nèi)存有可能被用光。如果這種情況發(fā)生,操作系統(tǒng)將不能在遇到操作符new 時分配所需的內(nèi)存,一個無效指針(null pointer)將被返回。因此,我們建議在使用new之后總是檢查返回的指針是否為空(null),如下例所示:
int * bobby;bobby = new int [5];
if (bobby == NULL) {
// error assigning memory. Take measures.
};
?
刪除操作符delete
既然動態(tài)分配的內(nèi)存只是在程序運行的某一具體階段才有用,那么一旦它不再被需要時就應該被釋放,以便給后面的內(nèi)存申請使用。操作符delete 因此而產(chǎn)生,它的形式是:
delete pointer;
或
delete [ ] pointer;
第一種表達形式用來刪除給單個元素分配的內(nèi)存,第二種表達形式用來刪除多元素(數(shù)組)的內(nèi)存分配。在多數(shù)編譯器中兩種表達式等價,使用沒有區(qū)別, 雖然它們實際上是兩種不同的操作,需要考慮操作符重載overloading (我們在后面的section 4.2節(jié)中將會看到)。
| // rememb-o-matic #include ?iostream.h? #include ?stdlib.h? int main ( ) { char input [100]; int i,n; long * l; cout << "How many numbers do you want to type in? "; cin.getline (input,100); i=atoi (input); l= new long[i]; if (l == NULL) exit (1); for (n=0; n<i; n++) { cout << "Enter number: "; cin.getline (input,100);? l[n]=atol (input); } cout << "You have entered: "; for (n=0; n<i; n++) { cout << l[n] << ", "; delete[] l; return 0; } | How many numbers do you want to type in? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32, |
這個簡單的例子可以記下用戶想輸入的任意多個數(shù)字,它的實現(xiàn)歸功于我們動態(tài)地向系統(tǒng)申請用戶要輸入的數(shù)字所需的空間。
NULL是C++庫中定義的一個常量,專門設計用來指代空指針的。如果這個常量沒有被預先定義,你可以自己定以它為0:
#define NULL 0
在檢查指針的時候,0和NULL并沒有區(qū)別。但用NULL 來表示空指針更為常用,并且更易懂。原因是指針很少被用來比較大小或被直接賦予一個除0以外的數(shù)字常量,使用NULL,這一賦值行為就被符號化了。
?
ANSI-C 中的動態(tài)內(nèi)存管理Dynamic memory in ANSI-C
操作符new 和delete 僅在C++中有效,而在C語言中沒有。在C語言中,為了動態(tài)分配內(nèi)存,我們必須求助于函數(shù)庫stdlib.h。因為該函數(shù)庫在C++中仍然有效,并且在一些現(xiàn)存的程序仍然使用,所以我們下面將學習一些關于這個函數(shù)庫中的函數(shù)用法。
?
函數(shù)malloc
這是給指針動態(tài)分配內(nèi)存的通用函數(shù)。它的原型是:
void * malloc (size_t nbytes);
其中nbytes 是我們想要給指針分配的內(nèi)存字節(jié)數(shù)。這個函數(shù)返回一個void*類型的指針,因此我們需要用類型轉(zhuǎn)換(type cast)來把它轉(zhuǎn)換成目標指針所需要的數(shù)據(jù)類型,例如:
char * ronny;ronny = (char *) malloc (10);
這個例子將一個指向10個字節(jié)可用空間的指針賦給ronny。當我們想給一組除char 以外的類型(不是1字節(jié)長度的)的數(shù)值分配內(nèi)存的時候,我們需要用元素數(shù)乘以每個元素的長度來確定所需內(nèi)存的大小。幸運的是我們有操作符sizeof,它可以返回一個具體數(shù)據(jù)類型的長度。
int * bobby;bobby = (int *) malloc (5 * sizeof(int));
這一小段代碼將一個指向可存儲5個int型整數(shù)的內(nèi)存塊的指針賦給bobby,它的實際長度可能是 2,4或更多字節(jié)數(shù),取決于程序是在什么操作系統(tǒng)下被編譯的。
?
函數(shù)calloc
calloc 與malloc 在操作上非常相似,他們主要的區(qū)別是在原型上:
void * calloc (size_t nelements, size_t size);
因為它接收2個參數(shù)而不是1個。這兩個參數(shù)相乘被用來計算所需內(nèi)存塊的總長度。通常第一個參數(shù)(nelements)是元素的個數(shù),第二個參數(shù) (size) 被用來表示每個元素的長度。例如,我們可以像下面這樣用calloc定義bobby:
int * bobby;bobby = (int *) calloc (5, sizeof(int));
malloc 和calloc的另一點不同在于calloc 會將所有的元素初始化為0。
?
函數(shù)realloc
它被用來改變已經(jīng)被分配給一個指針的內(nèi)存的長度。
void * realloc (void * pointer, size_t size);
參數(shù)pointer 用來傳遞一個已經(jīng)被分配內(nèi)存的指針或一個空指針,而參數(shù)size 用來指明新的內(nèi)存長度。這個函數(shù)給指針分配size 字節(jié)的內(nèi)存。這個函數(shù)可能需要改變內(nèi)存塊的地址以便能夠分配足夠的內(nèi)存來滿足新的長度要求。在這種情況下,指針當前所指的內(nèi)存中的數(shù)據(jù)內(nèi)容將會被拷貝到新的地址中,以保證現(xiàn)存數(shù)據(jù)不會丟失。函數(shù)返回新的指針地址。如果新的內(nèi)存尺寸不能夠被滿足,函數(shù)將會返回一個空指針,但原來參數(shù)中的指針pointer 及其內(nèi)容保持不變。
?
函數(shù) free
這個函數(shù)用來釋放被前面malloc, calloc 或realloc所分配的內(nèi)存塊。
void free (void * pointer);
注意:這個函數(shù)只能被用來釋放由函數(shù)malloc, calloc 和realloc所分配的空間。
你可以參考C++ reference for cstdlib獲得更多關于這些函數(shù)的信息。
總結
以上是生活随笔為你收集整理的C++ 高级数据类型(四)—— 动态内存分配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebForm 使用点滴。。。。
- 下一篇: 如何在Lua与C/C++之间实现tabl