memset_s
memset, memset_s
在头文件 | | |
---|---|---|
void * memset(void * dest,int ch,size_t count); | (1) | |
errno_t memset_s(void * dest,rsize_t destsz,int ch,rsize_t count) | (2) | (自C11以来) |
1)将ch值(在转换为无符号字符后,就像通过(unsigned char)ch)复制到dest指向的对象的每个第一个计数字符中。
如果访问超出dest
数组的末尾,则行为未定义。如果dest
是空指针,行为是未定义的。
2)与(1)相同,只是在运行时检测到以下错误,并且如果dest和destsz本身有效,则在将ch存储到目标范围[dest,dest + destsz)的每个位置之后调用当前安装的约束处理函数:
dest
是一个空指针
如果由dest <count <= destsz指向的字符数组的大小,行为是未定义的; 换句话说,destsz的错误值不会暴露即将发生的缓冲区溢出。 作为所有边界检查函数,只有当__STDC_LIB_EXT1__由实现定义时,以及在包含string.h之前用户将__STDC_WANT_LIB_EXT1__定义为整数常量1时,memset_s才能保证可用。
参数
sext | - | 指向要填充的对象的指针 |
---|---|---|
ch | - | 填充字节 |
count | - | 要填充的字节数 |
destsz | - | 目标数组的大小 |
返回值
1) dest
副本
2)成功时为零,错误时为非零。 同样出错的是,如果dest不是空指针并且destsz有效,那么将destsz填充字节ch写入目标数组。
注意
如果此函数修改的对象在其余生命期内(例如,gcc bug 8537)不再被访问,则memset可能会被优化(在as-if规则下)。 因为这个原因,这个函数不能用来擦洗内存(例如,填充一个存储密码为零的数组)。 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
参考
- C11标准(ISO / IEC 9899:2011):
扩展内容
memcpymemcpy_s(C11) | 将一个缓冲区复制到另一个(功能) |
---|---|
wmemset(C95) | 将给定的宽字符复制到宽字符数组(函数)中的每个位置 |
| memset的C ++文档 |