動態內存管理函數的運用

一.malloc
void* malloc (size_t size);
定義:向內存(堆區)申請一塊連續的可用空間,並且返回指向這塊空間的地址。
因爲存在申請,所以我們需要對其申請的空間進行判定,是否申請到空間。
舉個例子

int *p = (int*)malloc(num*sizeof(int));
 if (NULL == p){
  perror("Application failed ");   //錯誤原因
  return 1;            
 }

這就是一個用malloc申請空間的過程。其中就包括了“申請的空間大小”以及定義的類型(void* malloc (size_t size))
優點:(相對於棧而言)堆上申請變量其可擴展性較高(也就是你需要多少,就可以申請多少),不到導致空間浪費,以及相對於棧區而言,堆區一次可申請的空間相比於棧區較大。
說到了棧區,咱們就來談談,咱們寫代碼朋友都知道,在棧區不需要區申請空間,而是定義一個變量就可以直接用。下面我們就拋出一個理解:
1.在棧區我們不需要申請空間,棧會自動申請自動釋放
2.在堆區,我們需要區申請空間,並且我上面提到在棧區空間自動釋放,所以在堆區我們還需要釋放空間(這個我們在後面文章講不釋放空間的危害)
二.calloc
void* calloc (size_t num, size_t size)
定義:跟malloc相似,只不過calloc會對申請的空間進行初始化
上面我沒有談calloc的內存問題,就是想要放在這裏去對比說明
在這裏插入圖片描述
在這裏插入圖片描述
這裏我們可以通過兩幅圖進行對比,就可以看出malloc和calloc的區別了,(malloc對申請的空間不做初始化,而calloc會做初始化)這裏細心的朋友就會發現第二幅圖,不是隻申請了12個字節碼,怎麼初始化的比12個字節還多,這就是我們接下來要談的,談這個之間我們先來了解一個我們剛纔所說的在堆區要釋放空間的函數。
三.free
定義:釋放堆區申請的空間。
下面我們舉個例子
在這裏插入圖片描述
這裏的紅色表示釋放的空間,這裏也可以看到,(不是隻申請了12個字節的空間嗎,怎麼釋放這麼多?)。
在談這個之前,我們再說一點,對於free這個函數,
1.釋放空間代表的是不去使用該空間,但是該指針仍然指向該空間,所以這個和讓p=NULL有一定的差距。
2.對於堆區而言,不支持整體申請,局部釋放的。

int *p = (int*)malloc(num*sizeof(int));
 if (NULL == p){
  perror("Application failed ");   //錯誤原因
  return 1;            
 }
 free(p);      //正確
 free(p+1);    //錯誤

3.如果在堆區只申請空間,而不釋放,就會導致內存泄漏(可用空間變少),這個也很容易理解,未釋放的空間別人也無法申請,就導致可用空間變少。
4.程序退出,空間自動釋放
下面我們就談談關於這個申請空間中的問題,在剛纔的例子中,大家也可以看到,自己實際申請的空間會大於自己需要的空間,我們說說原因:
多出來的空間用於系統管理:比如,我們在free的時候只傳了一個起始地址,他是如何釋放整個空間的了,這就是多出來的空間在“作怪”。
四.realloc
void* realloc (void* ptr, size_t size)
定義:在申請空間的基礎上,去調整空間的大小。
這裏說明關於空間調整問題:
將空間調小,這個我們不用提了,直接將數字以及內存地址帶入最終返回起始地址,而對於增大空間,這裏就會遇到一個問題:
如果該段空間的後面空間已經被別人使用,使得無法在原來空間後面繼續拓展怎麼半?
拓展方法:在堆空間上另找一個合適大小的連續空間來使用。並且函數返回的是一個新的內存地址。
我們還是舉個例子:
在這裏插入圖片描述
縮小空間,起始地址不變。
在這裏插入圖片描述
增大空間,其後有可用空間,起始地址不變。
在這裏插入圖片描述

增大空間,其後可用空間不足(因爲增大到4000字節,所以其後空間大概率不足),導致其要在堆空間上另找一個合適大小的連續空間來使用,返回新的地址。
關於動態內存管理,malloc,calloc,ralloc就說到這裏,有的地方解釋的不夠透徹,也希望讀者多多探討,也提前祝大家端午節快樂。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章