這次要談的兩個C語言內建函式:malloc, free。
功能與用法:
首先,我們要先知道他的功能為何!
malloc: 往memory_heap要記憶體
free : 釋放malloc的記憶體空間
另外,使用時別忘了包含 stdlib.h 這個標準函式庫。
(在 GCC 下編譯,如果忘記包含函式庫,大不了送你一個警告,自動幫你包入)
談到 memory_heap 這裡順便補充一下,以下是 memory 配置圖
相對的, heap 則是用來做動態宣告,不過這區域必須由程式設計者自己管理,拿取多少記憶體,不用時就必須由程式設計者跟系統講說可以釋放,才會被註銷。
global 專門放置宣告在全域的變數,因為是獨立的區塊,所以我們會發現以往在區域變數(stack)沒辦法開的大陣列,在這裡就可以開大一點(不過正規的做法還是動態配置)
constant 專門存放常數的地方,這一區域有嚴格的封閉性,會禁止程式對他進行寫入
code 存放你寫的程式碼,用來執行用
介紹記憶體結構完了,我們回歸正題,來看看今天的主角吧!
開始使用前,要先看一下他函式的原型,瞭解一下他是怎麼運行的。
malloc:
void * malloc ( size_t size );
傳入的參數為“想要”的空間,以 Byte 為單位,通常會使用 want_size*sizeof(Type) 來表示想要的空間,
回傳值為 void 形態的指標,必須強制轉型成想要的形態。
另外,如果函式執行成功回傳空間的起始位置,失敗則回傳NULL
值得一提的是使用 malloc 的時候,這個函式要的記憶體會比你想的還大,
多要的部分是拿來擺放跟這塊記憶體管理的相關資訊,
(對源代碼有興趣的人請點文末的參考連結)
使用時的範式如下:
Type *ptr = (Type *) malloc ( want_size*sizeof(Type) );
ptr 代表指向那塊記憶體的初始位置(概念上跟陣列一樣,使用上也雷同)
這樣就是跟 heap 拿 want_size 個 Type 形態(Byte大小)的空間。
free:
void free ( void * ptr );
沒有回傳值,只是把指標傳進去,
他會告訴 OS 說這塊記憶體不再使用,可以配置給別人
(同樣的要如何清掉這塊記憶體也是 OS 的事)
值得一提的是此函式是採用 call by value 的方式傳值,
所以原本指標所指的位置並不會被清掉,僅僅是修改記憶體管理資訊而已。
意味著就算使用完 free 還是有機會可以拿到那塊記憶體空間的資料,
不過這就已經屬於不安全的使用了!
說了這麼多,我們來看範例:
簡單地索取與釋放
/*
* malloc & free demo - True
* 12/24/2012
*/
#include <stdio.h>
#include <stdlib.h>
const int size = 100; //配置一百個單位
int main(int argc, const char *argv[])
{
// 整數陣列
int *m_ptr = NULL;
m_ptr = (int *) malloc (size*sizeof(int));
// 檢查配置是否失敗
if ( m_ptr == NULL ) {
printf("Can not allocate memory!\n");
exit(1);
}
// 字元陣列
char *c_ptr;
c_ptr = (char *) malloc (size*sizeof(char));
// 檢查配置是否失敗
if ( c_ptr == NULL ) {
printf("Can not allocate memory!\n");
exit(1);
}
// struct
typedef struct {
int a;
float b;
} List;
List *s_ptr = (List *) malloc (size*sizeof(List));
// 檢查配置是否失敗
if ( s_ptr == NULL ) {
printf("Can not allocate memory!\n");
exit(1);
}
// 配置完後就可以開心的使用了~
// 用法和陣列一模一樣,唯一要注意的是,不要動到指標,
// 不小心指到奇怪的地方是很危險的
// Important !
// 一定要記得 free 掉用完的 memory !
free(m_ptr);
free(c_ptr);
free(s_ptr);
//End of Code
return 0;
}
補充資料:
malloc的源代碼
0 意見:
張貼留言
湖水偶然間遇上詩人的一片雲,而你因為機緣踏入這裡
何不留下一絲的吉光片羽呢?