memset的用法
来源:互联网 发布:淘宝后台手机端 编辑:程序博客网 时间:2024/06/06 20:51
memset
目录
- 需要的头文件
- 函数原型
- 程序例
- memset函数详细说明
需要的头文件
在C中 <string.h> 在C++中 <cstring>函数原型
函数介绍
void *memset(void *s,int ch,size_t n); 函数解释:将 s 中前 n 个字节用 ch 替换并返回 s 。 memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法[1]。常见错误
第一: 搞反了 ch 和 n 的位置. 一定要记住如果要把一个char a[20]清零,一定是 memset(a,0,20); 而不是 memset(a,20,0); 第二: 过度使用memset,我想这些程序员可能有某种心理阴影,他们惧怕未经初始化的内存,所以他们会写出这样的代码: char buffer[20]; memset(buffer,0,sizeof(char)*20); strcpy(buffer,"123"); 这里的memset是多余的. 因为这块内存马上就被覆盖了,清零没有意义. 第三: 其实这个错误严格来讲不能算用错memset,但是它经常在使用memset的场合出现 int some_func(struct something *a){ … … memset(a,0,sizeof(a)); … } 这里错误的原因是VC函数传参过程中的指针降级,导致sizeof(a),返回的是一个 something* 指针类型大小的的字节数,如果是32位,就是4字节。常见问题
问:为何要用memset置零?memset(&Address,0,sizeof(Address));经常看到这样的用法,其实不用的话,分配数据的时候,剩余的空间也会置零的。 答:1.如果不清空,可能会在测试当中出现野值。你做下面的试验看看结果() char buf[5]; CString str,str1; //memset(buf,0,sizeof(buf)); for(int i = 0;i<5;i++) { str.Format(“%d “,buf[i]); str1 +=str ; } TRACE(“%s\r \n“,str1); ⒉其实不然!特别是对于字符指针类型的,剩余的部分通常是不会为0的,不妨作一个试验,定义一个字符数组,并输入一串字符,如果不用memset实现清零,使用MessageBox显示出来就会有乱码(0表示NULL,如果有,就默认字符结束,不会输出后面的乱码) 问: 如下demo是可以的,能把数组中的元素值都设置成字符1, #include <iostream> #include <cstring> using namespace std; int main() { char a[5]; memset(a,'1',5); for(int i = 0;i < 5;i++) cout<<a[i]<<" "; system("pause"); return 0; } 而,如下程序想把数组中的元素值设置成1,却是不可行的 #include <iostream> #include <cstring> using namespace std; int main() { int a[5]; memset(a,1,5);//如果这里改成memset(a,1,5 *sizeof(int))也不可以,因为memset按字节赋值。 for(int i = 0;i < 5;i++) cout<<a[i]<<" "; system("pause"); return 0; } 问题是: 1,第一个程序为什么可以,而第二个不行, 2,不想要用for,或是while循环来初始化int a[5];能做到吗?(有没有一个像memset()这样的函数初始化) 答: ⒈因为第一个程序的 数组a是字符型的,字符型占据内存大小是1Byte,而memset函数也是以字节为单位进行赋值的,所以你输出没有问题。而第二个程序a是整型的,使用 memset还是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。你看看你输出结果是否这样? ⒉如果用memset(a,1,20);(实际上与memset(a,1,5*sizeof(int))结果是一样的) 就是对a指向的内存的20个字节进行赋值,每个都用ASCⅡ为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4 字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了
程序例
#include <string.h> #include <stdio.h> #include <memory.h> memset函数
memset函数详细说明
1。void *memset(void *s,int c,size_tn) 总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。 2。例子 main(){ char *s="Golden Global View"; clrscr(); memset(s,'G',6);//貌似这里有点问题// 单步运行到这里会提示内存访问冲突//肯定会访问冲突,s指向的是不可写空间。 printf("%s",s); getchar(); return 0; } 【以上例子出现内存访问冲突应该是因为s被当做常量放入程序存储空间,如果修改为 char s[]="Golden Global View";则没有问题了。】 【应该是没有问题的,字符串指针一样可以,并不是只读内存,可以正常运行】 3。memset() 函数常用于内存空间初始化。如: char str[100]; memset(str,0,100); 4。memset()的深刻内涵:用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘memset(a,'\0',sizeof(a)); memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例: char a[100],b[50]; memcpy(b,a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。 strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例: char a[100],b[50]; strcpy(a,b); 如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。 ⒌补充:某人的一点心得 memset可以方便的清空一个结构类型的变量或数组。 如: struct sample_struct { char csName[16]; int iSeq; int iType; }; 对于变量 struct sample_strcut stTest; 一般情况下,清空stTest的方法: stTest.csName[0]={'\0'}; stTest.iSeq=0; stTest.iType=0; 用memset就非常方便: memset(&stTest,0,sizeof(struct sample_struct)); 如果是数组: struct sample_struct TEST[10]; 则 memset(TEST,0,sizeof(struct sample_struct)*10); 另外: 如果结构体中有数组的话还是需要对数组单独进行初始化处理的。- 参考资料
1. memset API reference .www.cplusplus.com [引用日期2012-08-16] .
摘自百度百科。
- memset函数的用法
- memset函数的用法
- memset的用法
- memset的用法
- memset的用法
- memset的用法
- 四极管:memset的用法
- memset的用法
- memset函数的用法
- memset的用法
- memset的用法
- memset的用法
- memset的用法
- memset函数的用法
- memset的用法
- memset函数的用法
- memset 的 一些 用法
- memset()的用法
- 通过new BitmapDrawable()方法将Bitmap转化为Drawable的getIntrinsicHeight()和getIntrinsicWidth() 问题。
- Linux下常用命令及举例
- 用javah 导出类的头文件, 常见的错误及正确的使用方法
- PL/SQL异常处理总结
- BB.Flashback.Pro.v4.1.1.2498.Cracked.by.yoza[UpK]
- memset的用法
- Android 4.2 Input 流程分析
- IOS设置静态库的生成目录为默认的build目录
- 小算法酱油笔记之数组压缩0
- ndk make: *** 没有规则可以创建
- 绑定变量(bind variables)、替换变量(substitution variables)
- 大家一起番茄吧!
- sqlite3 查询数据库表结构
- Codeforces Round #141 (Div. 2)——B