三 初始化重置函数
函数名称: 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的内存状态:
这样会导致输出该字符串时由于没有00字符终止符,导致输出一堆乱码,甚至崩溃的情况出现
当我们初始化内存地址为0后,再次观察状态2S的内存地址
此时空余的地址全部都置为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内存,我们发现内存全部未初始化,这里内存地址不统一是笔者俩次实验导致的,请不要介意
状态2-S内存,我们发现完整的拷贝一个4个字节的整形后,前4个字节被有效赋值
状态3-S内存,我们只初始化置0了第一个字节
状态4-S内存,我们初始化了2个int整形即8个字节
状态5-S内存,我们只拷贝了第一个字节
这样我们就清晰的清楚了关于拷贝字节应该注意的问题了,当需要拷贝一个结构或者类时,应该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后效果
生成结构体数组
初始化/清空结构体数组
------------------------------------- 分界线------------------------------------
-------------------------------------------------------------------------------
函数名称: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内存如下,未经初始化
状态2,S1内存如下:
状态3,strset能将s初始化为0,但是会额外将很多别的位也置零,造成“污染”
状态4,置为32无效,原因暂不清楚
状态5,直接崩溃
总结
综上比较可以发现,memset更加稳定有效,且适用范围更广,strset的功能memset均能完成,且GUN中无法找寻strset这一函数,故强烈推荐使用memset