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

memset 函數詳解:原型、用法陷阱與最佳實踐

     編輯:關於C語言

memset 函數詳解:原型、用法陷阱與最佳實踐

函數原型(ISO C / POSIX)

#include <string.h>
void *memset(void *s, int c, size_t n);

參數說明

  • s:目標內存區起始地址
  • c:填充字節值(取 unsigned char 低 8 位)
  • n:填充字節數

返回值:s(便於鏈式調用)。

核心語義

將 s 指向的前 n 個字節全部設置為 (unsigned char)c。以字節為單位填充,而非按整型、浮點型填充。

典型用法

// 1. 清零結構體/數組(最常用)
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));

// 2. 字符數組初始化
char buf[1024];
memset(buf, 'a', sizeof(buf));  // 填充 'a'

// 3. 動態分配內存清零
int *arr = malloc(100 * sizeof(int));
memset(arr, 0, 100 * sizeof(int));

⚠️ 常見陷阱

1. 非 0 值填充整型數組 ≠ 設置為該整數

int a[10];
memset(a, 1, sizeof(a));
// 結果:每字節為 0x01 → 整數值 0x01010101 (16843009),而非 1

結論:memset 僅適用於清零(0)、填充字符、或設置 -1(全 1 位模式,對有符號整數通常為 -1,但標準不保證)。

2. 指針/浮點數清零的可移植性

  • 指針:全 0 位模式不一定是空指針(雖然主流平台是)
  • 浮點數:全 0 位模式是 0.0(IEEE 754 保證),但 C 標準不強制

建議:指針用 NULL 或 0 顯式賦值;浮點數用 0.0 循環賦值。

3. 重疊內存區域

memset 無重疊檢查,源目重疊屬未定義行為(實際上單方向寫入通常安全,但不應依賴)。

性能優化提示

  • 編譯器會將 memset(ptr, 0, n) 優化為向量化指令(SSE/AVX/NEON)或 rep stos
  • 大塊內存清零考慮 calloc(內核可能返回已清零頁面,延遲物理分配)
  • C++ 推薦 std::fill/std::fill_n(類型安全)或 std::memset(<cstring>)

安全替代方案

// C11 邊界檢查版本(可選實現)
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
errno_t memset_s(void *s, size_t smax, int c, size_t n);

C++ 現代寫法:

#include <algorithm> #include <vector>
std::fill(vec.begin(), vec.end(), 0);
std::array<int, 100> arr; arr.fill(0);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved