首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

編程好習慣:用 sizeof 杜絕內存操作長度錯誤

     編輯:關於C語言

前言

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 參數直接使用「被初始化的目標變數」,而非類型或宏。**

// 陣列: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));

兩條統一規則

  1. 目標是陣列 → sizeof(array_var)
    即使陣列嵌套在結構體中,sizeof 自動計算修改後的實際大小,無需手動同步。
  2. 目標是結構體指針 → sizeof(*ptr_var)
    解引用指針獲取實際類型大小,避免類型名拼寫錯誤或結構體變更未同步。

性能影響?零開銷

sizeof 是**編譯期運算子**,編譯器直接計算為常數嵌入機器碼,**無任何運行時開銷**。

心法總結

人腦處理「同一事務的多條規則」極易出錯。將「獲取初始化長度」固化為「直接對目標變數取 sizeof」單一規則,消除認知負荷,從源頭杜絕長度錯誤。本文出自「至簡李雲」博客。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved