memset, memset_s
来自cppreference.com
                    
                                        
                    
                    
                                                            
                    |   定义于头文件  <string.h>
  | 
||
|   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 转换到 unsigned char 后)到 dest 所指向对象的首 count 个字节。 若出现 dest 数组结尾后的访问则行为未定义。若 
dest 为空指针则行为未定义。2) 同 (1) ,除了若 
dest 与 destsz 自身有效,则存储 ch 于目标范围 [dest, dest+destsz) 的每个位置后,在运行时检测下列错误,并调用当前安装的制约处理函数:
-  
dest是空指针 -  
destsz或count大于 RSIZE_MAX -  
count大于destsz(会发生缓冲区溢出) 
-  
 
 若 
dest 所指向的字符数组大小 < count <= destsz; 则行为未定义,换言之,错误的 destsz 值不暴露行将发生的缓冲区溢出。
- 同所有边界检查函数, 
memset_s仅若实现定义了 __STDC_LIB_EXT1__ ,且用户在包含string.h前定义 __STDC_WANT_LIB_EXT1__ 为整数常量 1 才保证可用。 
参数
| dest | - | 指向要填充的对象的指针 | 
| ch | - | 填充字节 | 
| count | - | 要填充的字节数 | 
| destsz | - | 目标数组的大小 | 
返回值
1) 
dest 的副本,本质为更底层操作的临时内存地址,在实际操作中不建议直接使用此地址,操作完成以后,真正有意义的地址是dest本身。2) 成功时为零,失败时为非零。在失败时,若 
dest 不是空指针且 destsz 合法,则亦写入 destsz 个填充字节 ch 到目标数组。注意
若 memset 所修改的对象在其生存期的剩余部分不再被访问,则此函数可以被优化掉(在如同规则下)(例如 gcc 漏洞 8537 )。为此,此函数不能用于擦洗内存(例如以令填充存储密码的数组)。对 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 大于 destsz printf("str = \"%s\", r = %d\n", str, r); #endif }
可能的输出:
ghghghghghghghghghghgh aaaaahghghghghghghghgh str = "bbbbbhghghghghghghghgh", r = 0 str = "ccccchghghghghghghghgh", r = 22
引用
- C11 standard (ISO/IEC 9899:2011):
 
- 7.24.6.1 The memset function (p: 371)
 
- K.3.7.4.1 The memset_s function (p: 621-622)
 
- C99 standard (ISO/IEC 9899:1999):
 
- 7.21.6.1 The memset function (p: 333)
 
- C89/C90 standard (ISO/IEC 9899:1990):
 
- 4.11.6.1 The memset function
 
参阅
|    (C11)  | 
   将一个缓冲区复制到另一个  (函数)  | 
|    (C95)  | 
   将给定的宽字符复制到宽字符数组的所有位置  (函数)  |