C 中的動態記憶體分配

2021-09-26 15:34:14 字數 2346 閱讀 7628

目錄

為什麼分配動態記憶體?

堆的別名——空閒儲存器

new 和 delete 操作符

為陣列動態分配記憶體

在程式中處理固定數量的變數,這樣的應用非常有限。經常需要在執行期間根據程式的輸入資料來決定應給儲存不同型別的變數分配的空間量。例如,如果需要儲存乙個班的學生資訊,由於學生數目不固定,學生的名字長度也不一樣,因此最有效的處理該資料,肯定是在執行時動態地分配空間。

顯然,因為不可能在編譯期間定義任何動態分配的變數,所以源程式中將沒有它們的名稱。當建立這些變數時,計算機用記憶體中相應的位址來標識它們,該位址被儲存在指標中。

在大多數情況下,當執行程式時,計算機中有部分未使用的記憶體。這些內存在c++中被稱為堆,有時也稱為空閒儲存器。使用c++中的一種特殊操作符,可以在空閒儲存器中為特定型別的新變數分配空間。該操作符返回分配給變數的記憶體位址,它就是new操作符,與其配對的是delete操作符,其作用是釋放先前new分配的記憶體。

我們可以在程式中為某些變數在空閒儲存器中分配空間,當不再需要這些變數時,再將分配的空間釋放並返回給空閒儲存器。這樣在相同程式的後面,這部分記憶體就可以被其他動態分配的變數重用。這種技術非常強大,使我們可以高效地使用記憶體,而且在許多情況下,使用這種技術的程式可以處理許多原本不可能處理的、涉及大量資料的非常龐大的問題。

假設某個double變數需要空間。我們定義乙個指向double型別的指標,然後在執行時再請求分配記憶體。

double *p;

p = new double; //為double變數請求記憶體

第二行**中的new操作符應該返回空閒儲存器中分配給double變數的記憶體位址,並在指標p中儲存該位址。也就是說,將位址賦給p,現在p是位址,而*p是儲存在那裡的值。之後,根據間接定址運算子,可以通過指標p來引用double變數。

*p = 999.0;
p = new double(999.0);
當然也可以只用一條語句建立此指標並進行初始化:

double *p(new double(999.0));
當不再需要動態地分配某個變數時,可以用delete操作符將其占用的記憶體釋放到空閒存貯器中:

delete p;
這樣可以確保這塊記憶體以後可以被另乙個變數使用。如果不使用delete,隨後又在p指標中存入了乙個不同的位址值,那麼將無法再釋放這塊記憶體,或使用其包含的變數,因為我們失去了訪問該位址的途徑。這種情況稱為記憶體洩漏。

為陣列動態分配記憶體也非常簡單。如果我們希望分配乙個char型別的陣列,假設pstr是指向char型別的指標,則:

char *pstr;

pstr= new char [20];

該語句為20個字元的char陣列分配空間,並將其位址儲存到pstr中。

為了刪除剛才在空閒儲存器中建立的陣列,必須使用delete操作符。

delete  pstr;
注意,使用方括號是為了指出要刪除的是乙個陣列。從空閒儲存器中刪除陣列時,應該總是包括方括號,否則結果將不可預料。另外請注意,不用指定任何維數,只需寫出即可。

當然,指標pstr現在包含的位址可能已經分配給有其他用途的變數,因此我們當然不應該再使用該指標。當使用delete操作符拋棄之前分配的某些記憶體後,還應該總是將該指標重新設定成nullptr:

pstr = nullptr;
這樣確保我們不會試圖訪問已經刪除的記憶體。

當程式結束時,系統將釋放在空閒儲存器中給它分配的所有記憶體,但養成「將不再指向有效記憶體區域的指標復位成nullptr」這樣的習慣,是沒有壞處的。

總之,使用new和delete時,應遵守以下規則:

(1)不要使用delete來釋放不是new分配的記憶體;

(2)不要使用delete釋放同乙個記憶體塊兩次;

(3)如果使用new為陣列分配記憶體,則應使用delete來釋放;

例1:使用new來建立動態陣列,以及使用陣列表示法來訪問元素。

#includeusing namespace std;

int main()

{ int i;

int *p=new int[3]; //建立指標*p,它指向包含3個int值的記憶體塊中的第乙個元素;

參考:

c語言動態記憶體分配 C 動態記憶體分配

動態記憶體分配 雖然通過陣列就可以對大量的資料和物件進行有效地管理,但是很多情況下,在程式執行之前,我們並不能確切地知道陣列中會有多少個元素。這種情況下,如果陣列宣告過大,就會造成浪費 宣告過小,就會影響處理。在c 中,動態記憶體分配技術可以保證程式在執行過程中按照需要申請適量記憶體,使用後釋放,從...

C 中的動態記憶體分配

常見的程式崩潰的原因 由assert 觸發的 操作記憶體時,越界了 記憶體沒有被初始化就拿去用了 棧溢位了 使用了野指標。總之,非法操作記憶體會對引起程式崩潰。c中動態記憶體管理方式 使用malloc calloc realloc free進行動態記憶體管理。malloc calloc reallo...

c 動態記憶體分配

c語言中提供的動態記憶體分配為了解決陣列的靜態的分配方式的問題 即陣列大小必須在定義時指定,程式在執行時不能動態改變陣列的大小 在標準庫中提供了三個動態記憶體分配的函式供程式呼叫,下面將分別對這三個函式進行介紹 1.void malloc size t size malloc 在分配一段連續的記憶體...