C C 程式設計 動態記憶體

2021-07-08 14:28:09 字數 2359 閱讀 7369

在使用陣列的時候,總有乙個問題困擾著我們:陣列應該有多大?

例如編寫程式求n階行列式的值,用陣列表示行列式,需如下定義:

#define n 10    //陣列定義時方括號內必須是常量

double a[n][n]; //n*n二維陣列表示二階行列式

而以下定義形式則是錯誤的:(c++在codeblocks下無此問題)

int n;

scanf("%d",&n);     //輸入n值

double a[n][n]=;//意圖由輸入n值確定陣列大小

在很多情況下,並不知道實際執行時陣列到底有多大,那麼就要把陣列定義得足夠大,並且執行時要對下標做限制。否則,當定義的陣列不夠大時可能引起陣列越界,導致嚴重錯誤。如果因為某種特殊原因對陣列的大小有增加或減少,則 必須去重新修改和編譯程式。之所以出現這樣的問題是因為靜態記憶體分配。

c語言記憶體分配有兩種方式:靜態分配和動態分配。

靜態分配:在編譯時為程式中的資料物件分配相應的儲存空間。例如程式中所有的全域性變數和靜態變數,函式中的非靜態區域性變數等。由於是在編譯時為資料物件分配儲存空間,因此就要求在編譯時空間大小是明確的,所以陣列的長度必須是常量。而一旦編譯完成,陣列的長度在執行期間就是固定的。

動態記憶體:程式執行期間根據實際需要動態地申請或釋放記憶體的方式,不需要預先分配儲存空間,而是根據程式的需要適時分配,且分配的大小就是程式要求的大小。

靜態分配的內存在程式記憶體布局的資料區和棧區中,動態分配的內存在程式的堆區中。堆區的儲存空間的上限是物理記憶體的上限,因此動態記憶體分配可以得到比靜態記憶體分配更大的記憶體空間。

動態記憶體的缺點是執行效率不如靜態分配,因為動態記憶體的分配和釋放會產生額外的呼叫開銷。在實際程式設計中,在執行時分配或記憶體大小需要隨時調整等情況下才使用。

c語言動態記憶體管理通過標準庫函式實現,標頭檔案為:stdlib.h

1.動態記憶體分配函式

(1)malloc函式:分配乙個指定大小的記憶體空間

函式原型: void *malloc(size_t size);

若分配成功,則返回乙個指向該記憶體空間起始位址的void型指標;若分配失敗,則返回0值指標null。

*在實際程式設計中,malloc函式返回的void型別指標可以顯式轉換為其他指標型別。

*呼叫函式時,一般使用sizeof計算記憶體空間大小。

*需要注意,分配得到的記憶體空間是未初始化的。

例如:分配乙個int型記憶體空間

int *p;

p=(int *)malloc(sizeof(int));

若分配成功,p指向分配得到的記憶體單元,*p表示該記憶體單元。顯然,動態記憶體分配得到的儲存空間要按指標方式訪問。一般情況下p值不能改變,否則該記憶體單元的起始位址就「永遠是個謎」。

分配失敗的主要原因是沒有足夠的記憶體空間,所以在記憶體分配後,要檢查返回值,確保指標是否有效。

if(p!=null)

(2)calloc函式:分配n個連續指定大小的記憶體空間

函式原型: void *calloc(size_t nmemb,size_t size);

例如:分配50個int型記憶體空間

int *p;

p=(int *)calloc(50,sizeof(int));//等價於p=(int *)malloc(50*sizeof(int));

2.動態記憶體調整函式

recalloc函式:調整已分配記憶體空間大小

函式原型:void *realloc(void *ptr,size_t size);

3.動態記憶體釋放函式

free函式:釋放動態分配的記憶體空間

函式原型:void free(void *ptr);

引數指標ptr指向已有的動態記憶體空間。

int *p;

p=(int *)malloc(sizeof(int));

if(p!=null)

free(p);//釋放p指向的記憶體空間,指標p變成迷途指標

p=null;//避免產生「迷途指標」

動態記憶體不同於靜態記憶體,在實際程式設計中應注意以下幾點:

(1)靜態記憶體管理由編譯器進行,程式設計師只做物件定義(相當於分配);而動態記憶體管理按程式設計師的指令進行。

(2)動態記憶體分配和釋放必須對應,即有分配必須有釋放,不釋放記憶體會產生記憶體洩露,後果是隨著程式執行多次,可以使用的記憶體空間越來越小;另一方面,再一次釋放已經釋放的記憶體空間會導致程式出現崩潰性錯誤。

(3)靜態分配記憶體的生命期由編譯器自動確定,要麼是程式執行期,要麼是函式執行期。動態分配的記憶體生命期由程式設計師決定,即從分配開始,至釋放結束。特別地,動態分配的記憶體的生命期可以跨多個函式。

(4)靜態分配記憶體的物件有初始化,動態分配記憶體一般需要人為指令賦初始值。

(5)避免釋放記憶體後出現「迷途指標」,應及時設定為空指標。   

C C 動態記憶體管理

一 c語言中動態記憶體管理方式 c語言中使用 malloc calloc realloc free進行記憶體的管理和釋放 1.malloc動態記憶體申請 int ptest int malloc 10 sizeof int 申請記憶體的方式 free 釋放 2.calloc 該函式會將申請的記憶體空...

C C 動態記憶體管理

注意malloc free new delete new delete一定要匹配使用,否則可能出現記憶體洩漏甚至崩潰的問題小結 1 兩組函式都負責動態記憶體管理 2 malloc free是c c 標準庫的函式,而new delete是c 操作符。3 malloc free只負責動態分配空間 釋放空...

C C 動態記憶體管理

c語言動態記憶體管理 malloc calloc realloc free int p1 int malloc sizeof int malloc返回值型別為void int p2 int calloc 1,sizeof int 動態分配並初始化為0 int p3 int realloc p1,si...