C

memset

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才能保证可用。

参数

dest-指向要填充的对象的指针
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 ++文档 |