memset()函数中的坑
一 写在开头
1.1 本节内容
内存填充函数memset()中的坑。
二 函数原型
1 /* 来自man memset */ 2 #include <string.h> 3 void * memset(void * s, int c, size_t n);
功能描述:memset()函数用常量c的值填充由指针s所指向的内存地址空间的前n个字节的内存空间。
DESCRIPTION : The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
参数:
void * s - 指向要被填充的内存空间的首地址
int c - 一个常量
size_t n - 要被填充的字节数
返回值:
memset()函数是有返回值的,从函数原型也可以看出来。memset()函数返回一个指向内存空间s的指针。
RETURN VALUE : The memset() function returns a pointer to the memory area s.
三 填坑运动
3.1 第一个坑
先举一个memset()正确的应用场景。下面的代码能够很好地运行,完全能够达到目的。
1 #include <stdio.h> 2 #include <string.h> 3 4 int main(int argc, char *argv[]) 5 { 6 char Queen[10]; 7 8 memset(Queen, 'G', sizeof(Queen)); 9 10 return 0; 11 }
调用memset()函数之前:
(gdb) p Queen
$1 = "\360\005@\000\000\000\000\000\240\004"
调用memset()函数之后:
(gdb) p Queen
$2 = "GGGGGGGGGG"
如果Queen数组类型不是char而是int,结果会怎样?
1 #include <stdio.h> 2 #include <string.h> 3 4 int main(int argc, char *argv[]) 5 { 6 int Queen[10]; 7 8 memset(Queen, 'G', sizeof(Queen)); 9 10 return 0; 11 }
调用memset()函数之前:
(gdb) p Queen
$1 = {0, 0, 0, 0, 4195824, 0, 4195488, 0, -8352, 32767}
调用memset()函数之后:
(gdb) p Queen
$2 = {1195853639, 1195853639, 1195853639, 1195853639, 1195853639, 1195853639,
1195853639, 1195853639, 1195853639, 1195853639}
看到了吧!Queen数组全部被填充了一个相同的数字,但该数字却不是我们想要的'G'。为什么会这样?道理很简单,memset()函数是一个字节一个字节地填充数字的,你一个int类型变量在内存中占了4个字节(不同机器,int所占字节数不一样),不出错才怪!上一个例子之所以能够正确运行,是因为在我的机器上,一个char类型变量刚好占了一个字节。
怎么避免这个问题?下次记得在使用memset()函数对int型数组进行填充时,所能够使用的常量c的取值只能是0和-1。想想0和-1这两个数的二进制表示是怎样的,你就明白了为什么只能使用这两个数字了。
3.2 第二个坑
在成功避开第一个坑之后,你可能还会遇到第二个坑。比如说,你把上述的代码写成了下面的这个样子。
1 #include <stdio.h> 2 #include <string.h> 3 4 int main(int argc, char *argv[]) 5 { 6 int Queen[10]; 7 8 memset(Queen, -1, 10); 9 10 return 0; 11 }
调用memset()函数之前:
(gdb) p Queen
$1 = {0, 0, 0, 0, 4195824, 0, 4195488, 0, -8352, 32767}
调用memset()函数之后:
(gdb) p Queen
$2 = {-1, -1, 65535, 0, 4195824, 0, 4195488, 0, -8352, 32767}
怎么回事,为什么没有把Queen数组全部初始化为-1?因为memset()函数是一个字节一个字节地填充数的!第三个参数10表示的是数组Queen中有10个int型数据,它并不表示Queent数组在内存中所占的字节数!明白了吧!
怎么避免这个问题,很简单,将上述memset()调用改成如下的样子就好了
1 memset(Queen, -1, sizeof(Queen));
四 参考资料
1. man memset
上一篇: 你不知道人还说你天天生病呢
下一篇: CSU 1216异或最大值