再也不怕分配記憶體了
阿新 • • 發佈:2020-08-22
最近改使用者組管理專案bug時,遇到一個關於記憶體分配的問題。原來是同事用一個長度為4096的字元陣列分配記憶體,
strncpy()函式造成拷貝錯誤,導致使用者組管理編輯、新增和刪除功能不可用。
雖然是個小問題,但是記憶體分配一直都是很重要的,嚴重時會導致系統崩潰。
一、記憶體分配方式
靜態儲存區域中分配(系統分配,如全域性變數、static變數)
棧中進行分配(系統分配,如字元陣列)
堆中進行分配(使用者動態分配,涉及malloc、calloc、realloc、free函式)
二、常見錯誤及解決方案
- 使用未分配的記憶體
- 使用記憶體之前檢查指標是否為NULL
- 賦予初值,即便是賦予零值也不可省略;
- 使用了分配成功但是未初始化的記憶體,導致野指標;
- 記憶體分配且初始化了,但是進行了越界操作
- 注意下表的使用不能超出邊界
- 忘記釋放記憶體造成記憶體洩漏;
- 申請記憶體的方式和釋放記憶體的方式需要成雙成對
- free後,未將指標置為NULL,導致也野指標;
- 使用free記憶體之後,把指標置為NULL
1. 專案問題
專案中的記憶體分配方式就是棧分配,靜態分配,當輸入的變數長度超過字元陣列最大長度時,記憶體越界。
static int deleteRedUsr(int groupID, char *users, long long eventID) { /* some code */ char usrs[4096] = {0}; //當strlen(users) > 4094則會記憶體越界 strncpy(usrs, users, strlen(users)); /* some code */ }
2. 專案解決方案
不推薦擴大字元陣列,而應該使用動態分配記憶體
/* * 釋放記憶體,並將指標置為NULL * 最好在工具標頭檔案,重複使用 */ #define FREE(a) if( a!= NULL ){ free(a); a=NULL; } static int deleteRedUsr(int groupID, char *users, long long eventID) { /* some code */ char *usrs = NULL; usrs = (char *)malloc(strlen(users) + 1); //動態分配記憶體 strcpy(usrs, users); /* some code */ FREE(usrs); //在每個return前,釋放記憶體,避免記憶體洩漏 /* some code */ }