memset()、snprintf()、strncpy() 等內存操作函數最常見的 Bug 是**長度參數錯誤**。本文展示三類典型錯誤、常規修正、以及用 sizeof 固化為習慣的根治方案。
// 錯誤 1:指標陣列 vs 元素大小混淆
char *buf[FAIP_WITHDOT_MAX_LEN+1];
memset(buf, 0, FAIP_WITHDOT_MAX_LEN + 1); // 應乘 sizeof(char*)
// 錯誤 2:宏定義不一致
#define DIGEST_LEN 17
#define DIGEST_MAX 16
char digest[DIGEST_MAX];
memset(digest, 0, DIGEST_LEN); // 寫越界!應用 DIGEST_MAX
// 錯誤 3:malloc 類型與 memset 類型不匹配
dll_node_t *p = malloc(sizeof(dll_node_t));
memset(p, 0, sizeof(dll_t)); // 結構體大小不同!
// 修正 1
memset(buf, 0, sizeof(char*) * (FAIP_WITHDOT_MAX_LEN + 1));
// 修正 2
memset(digest, 0, DIGEST_MAX);
// 修正 3
memset(p, 0, sizeof(dll_node_t));
**核心原則:sizeof 參數直接使用「被初始化的目標變數」,而非類型或宏。**
// 陣列:sizeof(陣列變數)
char *buf[FAIP_WITHDOT_MAX_LEN+1];
memset(buf, 0, sizeof(buf));
// 陣列:sizeof(陣列變數)
char digest[DIGEST_MAX];
memset(digest, 0, sizeof(digest));
// 指針指向的結構體:sizeof(*指針變數)
dll_node_t *p = malloc(sizeof(dll_node_t));
memset(p, 0, sizeof(*p));
sizeof(array_var)sizeof 自動計算修改後的實際大小,無需手動同步。sizeof(*ptr_var)sizeof 是**編譯期運算子**,編譯器直接計算為常數嵌入機器碼,**無任何運行時開銷**。
人腦處理「同一事務的多條規則」極易出錯。將「獲取初始化長度」固化為「直接對目標變數取 sizeof」單一規則,消除認知負荷,從源頭杜絕長度錯誤。本文出自「至簡李雲」博客。