巧用goto解決記憶體洩露問題
阿新 • • 發佈:2018-12-09
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;
}