1. 程式人生 > >巧用goto解決記憶體洩露問題

巧用goto解決記憶體洩露問題

C語言記憶體洩露一直以來是個令人頭痛的問題,一不小心就會掉坑,老程式設計師也不能避免,這裡提出一種程式設計風格,試圖解決該問題。

//檢查malloc返回的指標,如果為空,則跳到label位置
#define MALLOC_CHECK(ptr, label) do{\
    if((ptr) == NULL)\
    {\
        goto label;\
    }\
}while(0)

//如果指標不為空,釋放之,並將指標置空
#define FREE_CHECK(ptr) do{\
    if(ptr)\
    {\
        alipay_iot_free(ptr);\
        ptr = NULL;\
    }\
}while
(0) char* function(void) { //所有變數在函式開始定義,並初始化,指標一定要初始化為NULL, //對於從堆裡面第一次獲取的記憶體,變數名字前面加下劃線(在使用過程中,可能會將改記憶體的指標賦值給另外的指標P,但是P不用加下劃線,避免重複釋放), //看到這種醜陋的標誌,我們會警惕,同時,在釋放時,可以作為匹配標誌,避免遺漏,即帶下劃線開始的指標,都應該在DONE中一起釋放。 char* ret = NULL;//不是第一次從對獲取的記憶體,不用加下劃線 char* _mem_ptr1 = NULL; int* _mem_ptr2 = NULL; char
* _mem_ptr3 = NULL; int* ptr = NULL; char buffer[10] = {0}; int length1 = 0; int length2 = 0; /*********************中間不需關心記憶體釋放的問題***********************/ _mem_ptr1 = get_name();//函式裡面申請記憶體 MALLOC_CHECK(_mem_ptr1, ERR);//檢查結果,如果函式返回NULL,跳到ERR //使用_mem_ptr1 _mem_ptr2 = malloc(sizeof(int
) * 10);//直接申請記憶體 MALLOC_CHECK(_mem_ptr2, ERR);//檢查申請結果,如果失敗,跳到ERR //使用_mem_ptr2 //同樣的使用_mem_ptr3 /*********************中間不需關心記憶體釋放的問題***********************/ ret = _mem_ptr3;//這個是要返回的,不要釋放,但要和DONE寫一起,便於和定義處匹配 DONE://統一釋放,只在此處釋放 FREE_CHECK(_mem_ptr1);//注意和定義處匹配 FREE_CHECK(_mem_ptr2);//注意和定義處匹配 return ret; ERR: ret = NULL; goto DONE; }