linux中memset的正确用法

【起因】希望对各种类型的数组进行初始化,避免野值

memset函数将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向S的指针。

      【函数头文件】 疑问提示:在linux中可以在terminal中输入 "man memset"进行查询

        #include<string.h>
        void *memset(void *s, int c, size_t n);

      【使用说明】 The  memset()  function  fills  the  first  n  bytes of the memory area  pointed to by s with the constant byte c.
      【错误用法】
        int array[10];
        memset(array,1,10);//或者memset(array,1,sizeof(array)),都是不对的!

      【解释】
       之前一直不明白为什么memset这个函数的头文件是 "string.h",看完下面的内容,你就会明白了。

       memset函数使用说明中提到的是按照byte来填充。

       举例来说
       char arr[10]; memset(arr,'a',10);
       由于char只占一个字节(byte),因此函数的结果是将连续的10个字节都填充为'a'。这是我们所期待的结果!

       int arr[10];memset(arr,1,10);
       由于int占4个字节(byte),因此"1"对应的二进制(32bits下)为"00000000000000000000000000000001"(4bytes),塞到1byte(8bit)的中,高位被舍弃了。所以,填入数组中的值是"00000001"。然而总共有10*4=40个byte,却只有10个byte被填充,因此结果是"00000001……00000001**********"(前面总共10个"00000001")。因此,第一个数是"0x01010101"=16843009(10进制)数组其余部分的值则是随机值,读取出来会是很离谱的数!
       有人说,可以这样memset(arr,1,sizeof(arr));
       其实这样做,就是将数组的所有值都填充为"0x01010101",也就是int数组的初始值变为了16843009
 !这确实有点出乎我们的预料!

  【正确用法】
   方法一:可以用任何值来初始化char数组!比如 memset(arr,'a',10);
   方法二:可以用"0"来初始化任何类型数组!比如 memset(arr,0,sizeof(arr));//arr可以是char或int等类型数组!

  【小结】版权所有,如有转载请注明出处:blog.csdn.net/whuslei
   不难看出为什么memset在"string.h"头文件中声明了,因为他是以byte为单位来处理的,而char正好是一个byte!
   用"0"来初始化数组时,要初始化的长度最好用sizeof(arr)来计算,这样避免出错!是不是很强大?
   当然,并非任何时候都需要初始化!详情请参考http://www.cublog.cn/u1/49221/showart_422256.html


程序例

#include <string.h>   

#include <stdio.h>   

#include <memory.h>


 

int main(void)   

{   

   char buffer[] = "Hello world/n";  

 printf("Buffer before memset: %s/n", buffer);  

 memset(buffer, '*', strlen(buffer) );  

 printf("Buffer after memset: %s/n", buffer);  

 return 0;   

}   

 

输出结果:   

Buffer before memset: Hello world   

Buffer after memset: ***********  

 

编译平台:   Microsoft Visual C++ 6.0   

 

也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。

 

例如下面这样:  

 

int array[5] = {1,4,3,5,2};   

for(int i = 0; i < 5; i++)   

cout<<array[i]<<" ";  

cout<<endl;   

memset(array,0,5*sizeof(int));   

for(int k = 0; k < 5; k++)   

cout<<array[k]<<" ";   

cout<<endl;   

 

输出的结果就是:   

1 4 3 5 2  

0 0 0 0 0   

后面的表大小的参数是以字节为单位,所以,对于int或其他的就并不是都乘默认的1(字符型)了。而且不同的机器上int的大小也可能不同,所以最好用sizeof()。     

 

要注意的是,memset是对字节进行操作 , 所以上述程序如果改为 :

int array[5] = {1,4,3,5,2};   

for(int i = 0; i < 5; i++)   

cout<<array[i]<<" ";   

cout<<endl;   

memset(array,1,5*sizeof(int));

// 注意 这里与上面的程序不同   

for(int k = 0; k < 5; k++)  

cout<<array[k]<<" ";   

cout<<endl;   

 

输出的结果就是:  

1 4 3 5 2   

16843009 16843009 16843009 16843009 16843009   

为什么呢 因为memset是以字节为单位就是对array指向的内存的5个字节进行赋值,每个都用 ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是 00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。   

 

所以用memset对非字符型数组赋初值是不可取的   

例如有一个结构体Some x,可以这样清零:   memset( &x, 0, sizeof(Some) );   

如果是一个结构体的数组Some x[10],可以这样:     memset( x, 0, sizeof(Some)*10 );


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值