memset, memset_explicit, memset_s
来自 cppreference.cn
定义于头文件 <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 数组末尾之外,则行为未定义。如果
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
|