Mem系列函数与Str系列函数总结 (三) memset 与 strset

三 初始化重置函数


函数名称: memset

函数原型:void *memset(void *s, int ch, size_t n);

函数功能:在一段内存块中填充某个给定的值,是对较大的结构体或数组进行清零操作的最快方法。

参数说明:void *s ― 待初始填充的内存首地址

         int ch  ― 待填充的ASCII码

        size_t n ― 待初始化填充的字节个数


用法

提起memset,通常都是在alloc或者new一块地址后,用来初始话置0的,这么做有什么好处呢?

void main()
{
  char * S = new char[10];
  char * S1 = "Frankie";
  memcpy(S,S1,7);//状态1―S内存地址
  memset(S,0,10);
  memcpy(S,S1,7);//状态2―S内存地址
}

我们看上述代码,在状态1时,由于没有memset初始化S对应的内存空间,当执行赋值操作后,我们可以观察S的内存状态:

wKiom1MgUKqwj64MAABhrVGJEzM353.jpg

这样会导致输出该字符串时由于没有00字符终止符,导致输出一堆乱码,甚至崩溃的情况出现

当我们初始化内存地址为0后,再次观察状态2S的内存地址

wKiom1MgURPB9XtmAAB5ACGY4z0205.jpg

此时空余的地址全部都置为0,不会出现输出乱码的问题



注意事项

对于上述例子而言,由于char占用一个字节,故不会出现问题,但是如果我们初始化重置的是一个int,double等多字节数据类型时,就可能出现异常,例如

void main()
{
  int S1 = 10000;
  int * S = new int[2];//状态1
  int * S2 = &S1;
  memcpy(S,S2,sizeof(int)*1);//2状态
  memset(S,0,1);//3状态
  memset(S,0,sizeof(int)*2);//4状态
  memcpy(S,S2,1);//5状态
}

状态1-S内存,我们发现内存全部未初始化,这里内存地址不统一是笔者俩次实验导致的,请不要介意

wKioL1MhHuCwQNZVAABYLFA5YLY141.jpg

状态2-S内存,我们发现完整的拷贝一个4个字节的整形后,前4个字节被有效赋值

wKioL1MhICzSUuPiAABV6fXxOEE473.jpg

状态3-S内存,我们只初始化置0了第一个字节

wKioL1MhIGvijDJDAABQ6J9fYlA398.jpg

状态4-S内存,我们初始化了2个int整形即8个字节

wKiom1MhIMaC0nJoAABYkzhUohY713.jpg

状态5-S内存,我们只拷贝了第一个字节

wKioL1MhINyBTReuAABYBAfW9rg663.jpg


这样我们就清晰的清楚了关于拷贝字节应该注意的问题了,当需要拷贝一个结构或者类时,应该sizeof该结构或者类的大小,而不应该直接按照个数来写,因为mem函数中是以字节为单位进行处理的。


PS:再补充一个利用memset清空结构体,或者清空/初始化结构体数组的方法,很实用

void main()
{
  struct Frankie
  {
     int age;
     char * name;
     double weight;
  };
                                                                                                                                                                                                                                                          
  struct Frankie WB ={27,"WB",75};
                                                                                                                                                                                                                                                          
  memset(&WB,0,sizeof(struct Frankie));//清空单个结构体
                                                                                                                                                                                                                                                          
  struct Frankie WBLover[100];
                                                                                                                                                                                                                                                          
  memset(WBLover,0,sizeof(struct Frankie)*100);//初始化结构体数组
                                                                                                                                                                                                                                                          
}

结果:

清空WB后效果

wKioL1MhJjvDAjQbAADKv648vG0572.jpg


生成结构体数组

wKiom1MhJonB__BuAAGvauyeW9M032.jpg


初始化/清空结构体数组

wKiom1MhJq7DOPz-AAGBLh6fVnk509.jpg




------------------------------------- 分界线------------------------------------

-------------------------------------------------------------------------------

函数名称:strset

函数原型:char *strset(char *s, int c);

函数功能:把字符串s中的所有字符都设置成ASK码

函数说明:不推荐使用,GCC下也没有找到该函数


原因

   一个字符串是以“/0"作为字符终止符的,但是当一个字符串未赋初始值时十不存在"/0"的,而strset会在它遇到该字符串的"/0"终止符之前一直初始化每一位为c,这样很危险,会污染其他数据,而且一般人都会使用memset代替strset来初始化字符串,故在此仅举一反例,不做过多介绍。


void main()
{
  char * S  = new char[4]; //状态1
  char * S1 = "ABC";//状态2
                                                                     
  strset(S,0);//状态3
  strset(S,32);//状态4
  strset(S1,0);//状态5
                                                                     
                                                                     
}

状态1,S内存如下,未经初始化

wKiom1MhQjKyDYoVAABODpInCi0873.jpg

状态2,S1内存如下:

wKiom1MhQlHAwxvhAABN1z-xCiE948.jpg

状态3,strset能将s初始化为0,但是会额外将很多别的位也置零,造成“污染”

wKioL1MhQnLShhJjAACptiEgD_w142.jpg

状态4,置为32无效,原因暂不清楚

wKioL1MhQqfxe0VQAACptiEgD_w479.jpg

状态5,直接崩溃



总结

综上比较可以发现,memset更加稳定有效,且适用范围更广,strset的功能memset均能完成,且GUN中无法找寻strset这一函数,故强烈推荐使用memset

你可能感兴趣的:(memset;,strset)