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的时候应该注意以上细节。

posted on 2018-04-02 15:09  archemiya  阅读(223)  评论(0编辑  收藏  举报

导航