#include
void *memset(void *ptr, int value, size_t num);
ptr 開始,將連續 num **字節** 設置為 value (取低 8 位)。ptr (鏈式調用)。struct Config cfg;
memset(&cfg, 0, sizeof(cfg)); // 一鍵歸零,含嵌套結構體、數組、指針
int arr[100];
memset(arr, 0, sizeof(arr)); // 等價 arr 初始化為 {0},但運行期執行
memset(ptr, num, value)// 正確:memset(目標, 填充值, 字節數)
memset(buffer, 0, 20); // 清零 20 字節
// 錯誤:memset(buffer, 20, 0); // 填充值 20,長度 0 → 無操作,極難發現
記憶口訣: 「目標、值、長」 — memset(where, what, how_many_bytes)。
int arr[5];
memset(arr, 1, sizeof(arr)); // 每字節 = 0x01
// arr[0] = 0x01010101 (16843009) ≠ 1 !
// arr[1] = 0x01010101 ...
// 只有 0 (全 0) 和 -1 (全 1, 即 0xFF) 適合逐字節填充產生預期整數值
memset(arr, -1, sizeof(arr)); // 每字節 0xFF → int = -1 (補碼全 1)
memset(arr, 0, sizeof(arr)); // 每字節 0x00 → int = 0
結論: memset 只能可靠地將整型/浮點數組設置為 **0** 或 **-1** (對應補碼全 0/全 1)。其他值請用循環賦值或 std::fill (C++)。
struct Node *p = malloc(sizeof(struct Node));
// 錯誤:memset(p, 0, sizeof(p)); // sizeof(p) = 4/8 (指針大小) → 僅清零指針變量本身,不清零分配的內存!
// 正確:
memset(p, 0, sizeof(*p)); // sizeof(*p) = sizeof(struct Node)
memset(p, 0, sizeof(struct Node)); // 同理
arr[i] = 0.0。NULL / nullptr。memset(this, 0, sizeof(*this)) 會破壞 vptr,導致虛函數調用崩潰。**C++ 類對象嚴禁 memset**。memset 不處理源目重疊 (它沒有源),但若 ptr 範圍覆蓋自身關鍵元數據 (如容器的 size/capacity 字段),會導致邏輯錯誤。memset(buf, 0, n) 為向量化指令 (SSE/AVX/NEON) 或 rep stosb,極快。**大塊內存清零首選 memset**。| 場景 | 推薦方式 | 理由 |
|---|---|---|
| 結構體/數組定義時清零 | Type obj = {0}; / Type obj{}; (C++11) | 編譯期/靜態初始化,最安全、無運行開銷 |
| 運行期重置大型結構體/緩衝區 | memset(&obj, 0, sizeof(obj)) | 極快,逐字節零填充 |
| 設置為特定非零值 (整型) | 循環賦值 / std::fill_n (C++) | memset 逐字節語義導致值錯誤 |
| 浮點數組初始化 | 循環 / std::fill / std::vector | 避免非標準浮點表示問題 |
| C++ 類對象 (含 vptr/非 POD) | 構造函數 / obj = Type{} / std::fill | memset 破壞對象語義 |
// 1. 安全清零宏 (C)
#define ZERO_OBJ(obj) memset(&(obj), 0, sizeof(obj))
// 使用
struct Config cfg;
ZERO_OBJ(cfg);
// 2. 分配並清零 (C)
void *ptr = malloc(size);
if (ptr) memset(ptr, 0, size);
// 3. C++ 現代替代 (針對 POD 類型)
#include
#include
std::fill(std::begin(arr), std::end(arr), 0); // 類型安全,可內聯優化
std::memset(arr, 0, sizeof(arr)); // 仍可用,但需確保 POD
sizeof(*ptr)。{0}/{},運行期大塊清零用 memset,非零填充用循環/算法。牢記「逐字節、順序、0/-1、對象大小、C++禁用」六字訣,memset 就是你手中最高效、最安全的內存清零利器。