memset, memset_explicit, memset_s
來自 cppreference.com
定義於標頭檔案 <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) 的每個位置之後(如果 dest
和 destsz
本身有效)呼叫當前安裝的 約束處理程式 函式。-
dest
是空指標 -
destsz
或count
大於 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_explicit
和 memset_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 函式
[編輯] 另見
(C11) |
將一個緩衝區複製到另一個緩衝區 (函式) |
(C95) |
將給定寬字元複製到寬字元陣列中的每個位置 (函式) |
C++ 文件 用於 memset
|