名稱空間
變體
操作

memset, memset_explicit, memset_s

來自 cppreference.com
< c‎ | string‎ | byte
定義於標頭檔案 <string.h>
void *memset( void *dest, int ch, size_t count );
(1)
void *memset_explicit( void *dest, int ch, size_t count );
(2) (自 C23 起)
errno_t memset_s( void *dest, rsize_t destsz, int ch, rsize_t count );
(3) (C11 起)
1) 將值 (unsigned char)ch 複製到 dest 指向的物件的第一個 count 個字元中的每個字元。
如果訪問超出目標陣列的末尾,則行為是未定義的。如果 dest 是空指標,則行為是未定義的。
2)(1) 相同,但對敏感資訊是安全的。
3)(1) 相同,但以下錯誤會在執行時檢測到,並在將 ch 儲存到目標範圍 [dest, dest+destsz) 的每個位置之後(如果 destdestsz 本身有效)呼叫當前安裝的 約束處理程式 函式。
  • dest 是空指標
  • destszcount 大於 RSIZE_MAX
  • count 大於 destsz(會發生緩衝區溢位)
如果 dest 指向的字元陣列的大小 < count <= destsz,則行為是未定義的;換句話說,destsz 的錯誤值不會暴露即將發生的緩衝區溢位。
與所有邊界檢查函式一樣,只有當實現定義了 __STDC_LIB_EXT1__ 並且使用者在包含 <string.h> 之前將 __STDC_WANT_LIB_EXT1__ 定義為整數常量 1 時,才能保證 memset_s 可用。

目錄

[編輯] 引數

dest - 指向要填充的物件的指標
ch - 填充位元組
count - 要填充的位元組數
destsz - 目標陣列的大小

[編輯] 返回值

1,2) dest 的副本
3) 成功時為零,錯誤時為非零。此外,如果發生錯誤,並且 dest 不是空指標且 destsz 有效,則將 destsz 個填充位元組 ch 寫入目標陣列。

[編輯] 注意

如果此函式修改的物件在其生命週期的其餘部分不再被訪問(例如,gcc bug 8537),則 memset 可能會被最佳化掉(根據 as-if 規則)。因此,此函式不能用於擦除記憶體(例如,用零填充儲存密碼的陣列)。

對於 memset_explicitmemset_s,禁止此最佳化:它們保證執行記憶體寫入。

第三方的解決方案包括 FreeBSD explicit_bzero 或 Microsoft SecureZeroMemory

[編輯] 示例

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main(void)
{
    char str[] = "ghghghghghghghghghghgh";
    puts(str);
    memset(str,'a',5);
    puts(str);
 
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    int r = memset_s(str, sizeof str, 'b', 5);
    printf("str = \"%s\", r = %d\n", str, r);
    r = memset_s(str, 5, 'c', 10);   // count is greater than destsz  
    printf("str = \"%s\", r = %d\n", str, r);
#endif
}

可能的輸出

ghghghghghghghghghghgh
aaaaahghghghghghghghgh
str = "bbbbbhghghghghghghghgh", r = 0
str = "ccccchghghghghghghghgh", r = 22

[編輯] 參考

  • C17 標準 (ISO/IEC 9899:2018)
  • 7.24.6.1 memset 函式 (p: 270)
  • K.3.7.4.1 memset_s 函式 (p: 451)
  • C11 標準 (ISO/IEC 9899:2011)
  • 7.24.6.1 memset 函式 (p: 371)
  • K.3.7.4.1 memset_s 函式 (p: 621-622)
  • C99 標準 (ISO/IEC 9899:1999)
  • 7.21.6.1 memset 函式 (p: 333)
  • C89/C90 標準 (ISO/IEC 9899:1990)
  • 4.11.6.1 memset 函式

[編輯] 另見

將一個緩衝區複製到另一個緩衝區
(函式) [編輯]
將給定寬字元複製到寬字元陣列中的每個位置
(函式) [編輯]
C++ 文件 用於 memset