簡介 malloc 與 free (C語言)

這次要談的兩個C語言內建函式:malloc, free。

功能與用法:

首先,我們要先知道他的功能為何!
    malloc: 往memory_heap要記憶體
    free  : 釋放malloc的記憶體空間
另外,使用時別忘了包含 stdlib.h 這個標準函式庫。
(在 GCC 下編譯,如果忘記包含函式庫,大不了送你一個警告,自動幫你包入)

談到 memory_heap 這裡順便補充一下,以下是 memory 配置圖

通常我們在函式宣告(靜態)變數的時候,會被擺放在 stack 的這塊區域裡,這塊記憶體的部分會由系統掌握,這意味著我們不需要對他進行管理,系統會幫我們處理(像是離開函式後變數會被註銷等等)。

相對的, 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 意見:

張貼留言

湖水偶然間遇上詩人的一片雲,而你因為機緣踏入這裡
何不留下一絲的吉光片羽呢?

關於我自己

在資訊工程走著的孩子,有太多的事情不懂,太多的東西想瞭解,一頭栽入無遠弗屆的世界!

搜尋此網誌

總網頁瀏覽量

技術提供:Blogger.