2014年(15)
分类: C/C++
2014-03-17 16:01:01
三 初始化重置函数
函数名称: memset
函数原型:void *memset(void *s, int ch, size_t n);
函数功能:在一段内存块中填充某个给定的值,是对较大的结构体或数组进行清零操作的最快方法。
参数说明:void *s — 待初始填充的内存首地址
int ch — 待填充的ASCII码
size_t n — 待初始化填充的字节个数
用法:
这样会导致输出该字符串时由于没有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函数中是以字节为单位进行处理的。
清空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