C 動態記憶體

2021-09-02 01:11:59 字數 3397 閱讀 8754

到目前為止,我們的程式中我們只用了宣告變數、陣列和其他物件(objects)所必需的記憶體空間,這些記憶體空間的大小都在程式執行之前就已經確定了。但如果我們需要記憶體大小為乙個變數,其數值只有在程式執行時 (runtime)才能確定,例如有些情況下我們需要根據使用者輸入來決定必需的記憶體空間,那麼我們該怎麼辦呢?

答案是動態記憶體分配(dynamic memory),為此c++ 整合了操作符new 和delete。

操作符 new 和 delete 是c++執行指令。本節後面將會介紹這些操作符在c中的等價命令。

操作符new 和new[ ]

操作符new的存在是為了要求動態記憶體。new 後面跟乙個資料型別,並跟一對可選的方括號[ ]裡面為要求的元素數。它返回乙個指向記憶體塊開始位置的指標。其形式為:

pointer = new type

或者pointer = new type [elements]

第乙個表示式用來給乙個單元素的資料型別分配記憶體。第二個表示式用來給乙個陣列分配記憶體。

例如:int * bobby;

bobby = new int [5];

在這個例子裡,作業系統分配了可儲存5個整型int元素的記憶體空間,返回指向這塊空間開始位置的指標並將它賦給bobby。因此,現在bobby 指向一塊可儲存5個整型元素的合法的記憶體空間,如下圖所示。

你可能會問我們剛才所作的給指標分配記憶體空間與定義乙個普通的陣列有什麼不同。最重要的不同是,陣列的長度必須是乙個常量,這就將它的大小在程式執行之前的設計階段就被決定了。而採用動態記憶體分配,陣列的長度可以常量或變數,其值可以在程式執行過程中再確定。

int * bobby;

bobby = new int [5];

if (bobby == null) ;

刪除操作符delete

既然動態分配的記憶體只是在程式執行的某一具體階段才有用,那麼一旦它不再被需要時就應該被釋放,以便給後面的記憶體申請使用。操作符delete 因此而產生,它的形式是:

delete pointer;

或delete [ ] pointer;

第一種表達形式用來刪除給單個元素分配的記憶體,第二種表達形式用來刪除多元素(陣列)的記憶體分配。在多數編譯器中兩種表示式等價,使用沒有區別, 雖然它們實際上是兩種不同的操作,需要考慮操作符過載overloading (我們在後面的section 4.2節中將會看到)。

// 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; nnull是c++庫中定義的乙個常量,專門設計用來指代空指標的。如果這個常量沒有被預先定義,你可以自己定以它為0:

#define null 0

在檢查指標的時候,0和null並沒有區別。但用null 來表示空指標更為常用,並且更易懂。原因是指標很少被用來比較大小或被直接賦予乙個除0以外的數字常量,使用null,這一賦值行為就被符號化了。

ansi-c 中的動態記憶體管理dynamic memory in ansi-c

操作符new 和delete 僅在c++中有效,而在c語言中沒有。在c語言中,為了動態分配記憶體,我們必須求助於函式庫stdlib.h。因為該函式庫在c++中仍然有效,並且在一些現存的程式仍然使用,所以我們下面將學習一些關於這個函式庫中的函式用法。

函式malloc

這是給指標動態分配記憶體的通用函式。它的原型是:

void * malloc (size_t nbytes);

其中nbytes 是我們想要給指標分配的記憶體位元組數。這個函式返回乙個void*型別的指標,因此我們需要用型別轉換(type cast)來把它轉換成目標指標所需要的資料型別,例如:

char * ronny;

ronny = (char *) malloc (10);

這個例子將乙個指向10個位元組可用空間的指標賦給ronny。當我們想給一組除char 以外的型別(不是1位元組長度的)的數值分配記憶體的時候,我們需要用元素數乘以每個元素的長度來確定所需記憶體的大小。幸運的是我們有操作符sizeof,它可以返回乙個具體資料型別的長度。

int * bobby;

bobby = (int *) malloc (5 * sizeof(int));

這一小段**將乙個指向可儲存5個int型整數的記憶體塊的指標賦給bobby,它的實際長度可能是 2,4或更多位元組數,取決於程式是在什麼作業系統下被編譯的。

函式calloc

calloc 與malloc 在操作上非常相似,他們主要的區別是在原型上:

void * calloc (size_t nelements, size_t size);

因為它接收2個引數而不是1個。這兩個引數相乘被用來計算所需記憶體塊的總長度。通常第乙個引數(nelements)是元素的個數,第二個引數 (size) 被用來表示每個元素的長度。例如,我們可以像下面這樣用calloc定義bobby:

int * bobby;

bobby = (int *) calloc (5, sizeof(int));

malloc 和calloc的另一點不同在於calloc 會將所有的元素初始化為0。

函式realloc

它被用來改變已經被分配給乙個指標的記憶體的長度。

void * realloc (void * pointer, size_t size);

引數pointer 用來傳遞乙個已經被分配記憶體的指標或乙個空指標,而引數size 用來指明新的記憶體長度。這個函式給指標分配size 位元組的記憶體。這個函式可能需要改變記憶體塊的位址以便能夠分配足夠的記憶體來滿足新的長度要求。在這種情況下,指標當前所指的記憶體中的資料內容將會被拷貝到新的位址中,以保證現存資料不會丟失。函式返回新的指標位址。如果新的記憶體尺寸不能夠被滿足,函式將會返回乙個空指標,但原來引數中的指標pointer 及其內容保持不變。

函式 free

這個函式用來釋放被前面malloc, calloc 或realloc所分配的記憶體塊。

void free (void * pointer);

注意:這個函式只能被用來釋放由函式malloc, calloc 和realloc所分配的空間。

你可以參考c++ reference for cstdlib獲得更多關於這些函式的資訊。

--------------------- 

原文: 

C 動態記憶體

了解動態記憶體在 c 中是如何工作的是成為一名合格的 c 程式設計師必不可少的。c 程式中的記憶體分為兩個部分 很多時候,您無法提前預知需要多少記憶體來儲存某個定義變數中的特定資訊,所需記憶體的大小需要在執行時才能確定。在 c 中,您可以使用特殊的運算子為給定型別的變數在執行時分配堆內的記憶體,這會...

C 動態記憶體

棧 在函式內部宣告的所有變數都將占用棧記憶體 堆 這是程式中未使用的記憶體,在程式執行時可用於動態分配記憶體 new和delet運算子 動態分配記憶體的通用語法 new data type 如果自由儲存區已被用完,可能無法成功分配記憶體。所以建議檢查 new 運算子是否返回 null 指標,並採取以...

C 動態記憶體

new 的功能是在堆區新建乙個物件,並返回該物件的指標。所謂的 新建物件 的意思就是,將呼叫該類的建構函式,因為如果不構造的話,就不能稱之為乙個物件。而 malloc 只是機械的分配一塊記憶體,如果用 mallco 在堆區建立乙個物件的話,是不會呼叫建構函式的。同樣的,用 delete 去釋放乙個堆...