memset函数浅析
NAME
memset - fill memory with a constant byte
SYNOPSIS
#include <string.h>
void *memset(void *s, int c, size_t n);
DESCRIPTION
The memset() function fills the first n bytes of the memory area
pointed to by s with the constant byte c.
RETURN VALUE
The memset() function returns a pointer to the memory area s.
ATTRIBUTES
For an explanation of the terms used in this section, see
attributes(7).
┌──────────┬───────────────┬─────────┐
│Interface │ Attribute │ Value │
├──────────┼───────────────┼─────────┤
│memset() │ Thread safety │ MT-Safe │
└──────────┴───────────────┴─────────┘
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD.
以上摘自archlinux的man页面。
描述项描述了memset()函数的功能,使用恒定字节c变量填充由指针s所指向的第一个n个字节的连续内存块。读起来不是那么的易懂。下面我们测试一下。
代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 int main(){ 5 int a[10]; 6 char b[10]; 7 memset(a,1,sizeof(a)); 8 memset(b,'A',sizeof(b)); 9 printf("%d\n",a[0]); 10 printf("%c\n",b[0]); 11 return 0; 12 }
运行结果
16843009
A
问题来了,为什么对于字符串的初始化正确而对于int数组的是错误的呢?
继续测试,这次我们使用
memset(a,0,sizeof(a));
结果为
0
这是为什么呢?
首先注意到,在man页面的描述项中所提到的是填充一段连续的内存块,对于内存来说最小的存储单位是1byte,而接下来说的constant byte其实指的就是1字节大小的c。这样我们第一次出现16843009就可以解释了。
使用1字节的大小,当c为1的时候,在1字节的内存中应表示为00000001,而一个int单位为4个字节,所以填充的时候变成00000001000000010000000100000001,即0x01010101,即16843009。
进一步测试
memset(a,511,sizeof(a));
结果为
-1
511在二进制中的表示为1,11111111(逗号表示隔位,看得更清楚)所以取1字节的大小则为11111111,表示的是-1,故结果为-1。
在使用memset的时候应该注意以上细节。