本文目錄一覽:
- 1、c語言中malloc是什麼?怎麼用?
- 2、C語言-動態分配內存 malloc & free
- 3、C語言如何用malloc函數開闢動態數組???
- 4、在C語言中如何使用malloc動態申請一維數組?
- 5、數據結構基礎之動態內存分配(malloc)
c語言中malloc是什麼?怎麼用?
malloc() 函數用來動態地分配內存空間,其原型為:void* malloc (size_t size);
說明:
【參數說明】
size 為需要分配的內存空間的大小,以位元組(Byte)計。
【函數說明】
malloc() 在堆區分配一塊指定大小的內存空間,用來存放數據。這塊內存空間在函數執行完成後不會被初始化,它們的值是未知的。如果希望在分配內存的同時進行初始化,請使用 calloc() 函數。
【返回值】
分配成功返回指向該內存的地址,失敗則返回 NULL。
操作:
由於申請內存空間時可能有也可能沒有,所以需要自行判斷是否申請成功,再進行後續操作。
如果 size 的值為 0,那麼返回值會因標準庫實現的不同而不同,可能是 NULL,也可能不是,但返回的指針不應該再次被引用。
注意:函數的返回值類型是 void *,void 並不是說沒有返回值或者返回空指針,而是返回的指針類型未知。所以在使用 malloc() 時通常需要進行強制類型轉換,將 void 指針轉換成我們希望的類型,例如:
#includestdlib.h
typedef int ListData;
ListData *data; //存儲空間基址
data = ( ListData * ) malloc( 100 * sizeof ( ListData ) );
擴展資料
實現malloc的方法:
(1)數據結構
首先我們要確定所採用的數據結構。一個簡單可行方案是將堆內存空間以塊的形式組織起來,每個塊由meta區和數據區組成,meta區記錄數據塊的元信息(數據區大小、空閑標誌位、指針等等)。
數據區是真實分配的內存區域,並且數據區的第一個位元組地址即為malloc返回的地址 。
(2)尋找合適的block
現在考慮如何在block鏈中查找合適的block。一般來說有兩種查找演算法:
First fit:從頭開始,使用第一個數據區大小大於要求size的塊所謂此次分配的塊
Best fit:從頭開始,遍歷所有塊,使用數據區大小大於size且差值最小的塊作為此次分配的塊
兩種方式各有千秋,best fit有較高的內存使用率(payload較高),而first fit具有較高的運行效率。這裡我們採用first fit演算法。
(3)開闢新的block
如果現有block都不能滿足size的要求,則需要在鏈表最後開闢一個新的block。
(4)分裂block
First fit有一個比較致命的缺點,就是可能會讓更小的size佔據很大的一塊block,此時,為了提高payload,應該在剩餘數據區足夠大的情況下,將其分裂為一個新的block。
(5)malloc的實現
有了上面的代碼,我們就可以實現一個簡單的malloc.注意首先我們要定義個block鏈表的頭first_block,初始化為NULL;另外,我們需要剩餘空間至少有BLOCK_SIZE+8才執行分裂操作
由於我們需要malloc分配的數據區是按8位元組對齊,所以size不為8的倍數時,我們需要將size調整為大於size的最小的8的倍數。
C語言-動態分配內存 malloc & free
需要用一個數組來保存用戶的輸入,但是卻不知道用戶會輸入多少條數據。
(1) 如果設一個太大的數組,則顯得浪費內存
(2) 如果設得太小,又怕不夠
問題:如何做到恰好夠用、又一點不浪費呢?
系統中存在一個內存管理器(MM, Memory Manager),它負責管理一堆閑置內存。它被設計用於解決此類問題。
MM提供的服務:應用程序可以向MM申請(借出)一塊指定大小的內存,用完之後再釋放(還回)。
應用程序在使用malloc時,要把返回值轉換成目標類型。
這塊內存和數組沒有本質區別,用法完全相同。
需要先計算需要多少位元組的內存空間
數組舉例子:
釋放的時候需要注意, 因為在for循環執行之後,p的地址往前移動了10, 所以需要減去10, 然後再釋放p,不然會有問題
// 當銷毀時只需要free一次,malloc了幾個位元組就會free幾個位元組,和char類型還是int類型無關
free(p);
在一個函數中動態分配的內存,在另一個函數中操作這塊內存
(1) MM是一個系統級的東西,所有的應用程序都向同一個MM申請內存。
(2) 何為借出?實際上,在內存被借出時,MM只是把它管理的內存標記了一下,表示該段內存已經被佔用。比如,它把每一段被佔用的內存給記錄下來(首地址,長度)
(p0,n0) (p1, n1) (p2, n2) …
(3) MM非常慷慨:①只要有人 malloc ,它都同意借出 ②你不歸還,它永遠不會主動要求你 free 。
(4) MM管理的內存區域稱為「堆」Heap
這意味著,用戶程序應該自覺得及時 free ,以便不耽誤別的應用程序的使用。如果有個應用程序不停地 malloc ,而不 free ,那最終會用光MM的內存。當MM沒有更多閑置內存時, malloc 返回 NULL ,表示內存已經用完。
再次重申: 應用程序在malloc之後,應該儘早free !
使用原則:需要的時候再申請,不需要的時候立即釋放
實際上,MM對借出的內存塊進行標識
(p0, n0) (p1, n1) (p2, n2) …
它內部已經保證任意兩塊內存不會「交疊」,即不會重疊,不會把一塊內存同時借給兩個應用程序使用。
所以,每塊內存的首地址都是不同的,在 free 的時候只需要指明首地址即可。
對象指的一塊內存
示例:用Citizen表示一個市民,用Car表示一個輛車。他起初沒有車,但未來可能有一輛車。
怎麼樣才算「及時」? 「不及時」會怎樣?
MM里可用的內存是有限的,你用完了就得儘快還,因為別的應用程序也需要MM的內存。
只借不還,積累到一定程度,MM沒有更多內存可用,於是malloc返回NULL。
要還就得全還,否則MM那邊處理不了
原因是:MM可能此時沒有閑置內存可用。(雖然這種情況一般不會發生)
free之後,該內存交還給MM,該內存不再可用(失效)
不一定要在相同的函數里釋放,在應用程序的任意一個角落釋放都是有效的。
也就是說:這一塊內存被malloc出來之後,完全交給你處置
功能:將 s 中當前位置後面的 n 個位元組 (typedef unsigned int size_t )用 ch 替換並返回 s
參數:
參數:
功能:由 src 所指內存區域複製 n 個位元組到 dest 所指內存區域。
memmove() 功能用法和 memcpy()) 一樣,區別在於: dest
和 src 所指的內存空間重疊時, memmove() 仍然能處理,不過執行效率比 memcpy() 低一些
C語言如何用malloc函數開闢動態數組???
函數原型為
void*malloc(unsigned int size);
其作用是在內存的動態存儲區中分配一個長度為size的連續空間。形參size的類型為無符號整型(不允許為負數)。返回值是所分配區域的第一個位元組的地址。如
malloc(100); //開闢100位元組的臨時分配域,返回值為其第一位元組的地址
在C語言中如何使用malloc動態申請一維數組?
malloc()函數用來動態地分配內存空間,其原型為:void*malloc(size_tsize);
描述:
(參數描述)
Size是以位元組為單位分配的內存空間量。
【功能描述】
Malloc()在堆中分配指定大小的內存空間來保存數據。函數執行後,此內存空間未初始化,且其值未知。如果希望在分配內存的同時進行初始化,可以使用calloc()函數。
(返回值)
分配成功時返回指向內存的地址,失敗時返回NULL。
操作:
由於在請求內存空間時,可能有內存空間,也可能沒有內存空間,所以在繼續之前,您需要自己決定應用程序是否成功。
如果size的值為0,返回值可能為NULL,也可能不為NULL,這取決於標準庫實現,但是不應該再次引用返回的指針。
注意:函數的返回值類型為void*,Void並不意味著沒有返回值或空指針,而是返回的指針類型未知。所以當你使用malloc()時,你通常需要將void指針轉換成你想要的類型,例如:
# include stdlib。H
TypedefintListData;
ListData*數據;//存儲空間的基本地址
Data=(ListData*)malloc(100*sizeof(ListData));
擴展資料:
實現malloc的方法:
(1)數據結構
首先,我們要確保數據結構。一個簡單可行的解決方案是將堆內存空間組織成塊,每個塊由一個元區域和一個數據區域組成,元區域記錄關於數據塊的元數據(數據區域大小、空閑標誌位、指針等)。
數據區域是實際分配的內存區域,數據區域的第一個位元組地址是malloc返回的地址。
(2)找到正確的街區
現在考慮如何在區塊鏈中找到合適的區塊。一般來說,有兩種搜索演算法:
Firstfit:從頭開始,使用第一個大於所需大小的數據塊稱為已分配的塊
最佳匹配:從頭開始遍歷所有塊,使用數據區域大小大於大小且分配的塊的差異最小的塊
最適合的有一個高的有效載荷和第一個適合有一個高的操作效率。這裡我們使用第一個fit演算法。
(3)創建一個新的塊如果現有的塊都不能滿足size的要求,則需要在列表的末尾創建一個新的塊。
(4)分塊先拼裝有一個致命的缺點,那就是它可能允許較小的尺寸佔據一個較大的塊。在這種情況下,為了改進有效負載,當剩餘的數據區域足夠大時,應該將其劃分為一個新的塊。
(5)malloc的實現
通過上面的代碼,我們可以實現一個簡單的malloc。注意,首先我們需要定義鏈表的第一個塊,first_block,初始化為NULL;此外,我們需要至少剩下的空間BLOCK_SIZE+8來執行除法操作
因為我們需要malloc分配數據區域在8位元組處對齊,所以大小不適用於8個倍數,所以我們需要調整大小,使其大於8的最小倍數的大小。
數據結構基礎之動態內存分配(malloc)
C語言提供了四個基本的動態內存管理(內存分配與釋放)函數,這些函數的原型包含在stdlib.h頭文件里。
它們分別是:
1.malloc()/free()函數
2.calloc()函數
3.realloc()函數
malloc的全稱是memory allocation,中文叫動態內存分配,用於申請一塊連續的指定大小的內存塊區域以void*類型返回分配的內存區域地址,當無法知道內存具體位置的時候,想要綁定真正的內存空間,就需要用到動態的分配內存,一般需和free函數配對使用。
本篇只對malloc進行講解
malloc()函數在堆中申請分配一個大小為size個位元組的連續內存空間,若成功分配,則返回一個指向 所分配空間起始地址 的指針,否則返回空指針(NULL)。
free()函數用來釋放已分配的內存空間,參數p是待釋放的內存空間的首指針
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/238889.html