memset的使用
来源:互联网 发布:windows一直检查更新 编辑:程序博客网 时间:2024/06/04 18:30
memest原型 (please type "man memset" in your shell)
void *memset(void *s, int c, size_t n);
memset:作用是在一段内存块中填充某个给定的值,它对较大的结构体或数组进行清零操作的一种最快方法。
常见的三种错误
第一: 搞反了c 和 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));
…
}
问:为何要用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)
2.其实不然!特别是对于字符指针类型的,剩余的部分通常是不会为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))也是不可以的
for(int i = 0;i < 5;i++)
cout<<a[i]<<" ";
system("pause");
return 0;
}
问题是:
1,第一个程序为什么可以,而第二个不行,
2,不想要用for,或是while循环来初始化int a[5];能做到吗?(有没有一个像memset()这样的函数初始化)
答:
1.因为第一个程序的数组a是字符型的,字符型占据内存大小是1Byte,而memset函数也是以字节为单位进行赋值的,所以你输出没有问题。而第二个程序a是整型的,使用memset还是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。你看看你输出结果是否这样?
2.如果用memset(a,1,20);
就是对a指向的内存的20个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是1000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。
首先是ZeroMemory和memset的区别: 1、ZeroMemory是微软的SDK提供的,memset属于C Run-time Library提供的。 2、ZeroMemory是一个宏,只是用于把一段内存的内容置零,内部其实是用 3、如果程序是Win32程序而且不想连接c运行时库,那就用ZeroMemory,如果需要跨平台,那就用memset。 所以如果ZeroMemory和memset用于清零操作,其本质是一样的。 然后说说ZeroMemory和 “={0}”的区别: 1、ZeroMemory会将结构中所有字节置0,而“={0}”只会将成员置0,其中填充字节不变。 2、一个struct有构造函数或虚函数时,ZeroMemory可以编译通过,而“={0}”会产生编译错误。其中,“={0}”的编译错误起到了一定的保护作用, 参看如下代码: struct SPerson class CTestVirtual /// 虚函数 int a; int main(int argc, char* argv[]) /// 安全操作 //// 会引起编译错误! CTestVirtual tv; //虚函数的指针已经被清零,因此程序运行到这里会引起崩溃! //0xC0000005: Access violation reading location 0x00000000. return 0; 因此,在windows平台下,数组或纯结构使用ZeroMemory是安全的,而类(class)就使用构造函数进行初始化,不要调用ZeroMemory。ZeroMemory、memset 和 “={0}” 三者区别:
因此ZeroMemory只能用于Windows系统,而memset还可用于其他系统。
memset实现的,而memset除了对内存进行清零操作,还可以将内存置成别的字符。
因为对一个有虚函数的对象使用ZeroMemory时,会将其虚函数的指针置0,这是非常危险的(调用虚函数时,空指针很可能引起程序崩溃)。
{
char c;
float s;
};
{
public:
CTestVirtual(){}
virtual int Draw()
{
return 10;
}
};
{
char sztmp[20];
/// 安全操作
ZeroMemory(sztmp, sizeof(sztmp));
SPerson sTest = {0};
int i = sizeof(SPerson);
//CTestVirtual otv = {0};
/// 危险操作!
ZeroMemory(&tv, sizeof(tv));
/// 因为对象没有使用虚指针调用函数,所以程序运行到这里不会崩溃
tv.Draw();
/// 将对象地址赋给指针
CTestVirtual *pTv = &tv;
//错误信息:Unhandled exception at 0x004010b1 in Solution.exe:
pTv->Draw();
}
另外,如果一个类的结构中包含STL模板(Vector、List、Map等等),那么使用ZeroMemory对这个类的对象中进行清零操作也会引起一系列的崩溃问题(指针指向内存错误、迭代器越界访问等)。
所以,再次强烈建议:类(class)只使用构造函数进行初始化,不要调用ZeroMemory进行清零操作。
- memset的使用
- memset的使用
- ZeroMemory (memset)的使用
- memset()的使用
- memset函数的使用
- 关于memset的使用
- 关于memset的使用
- memset的使用
- memset函数的使用
- memset的使用
- memset的使用
- memset的使用注意
- memset的正确使用
- 关于memset的使用
- 关于memset的使用
- memset的使用
- memset()的函数使用
- memset的使用问题
- 并口规范
- 在CSDN上共享了7个经典定位算法的MATLAB代码
- Lucene:基于Java的全文检索引擎简介--车东老师
- using ntsd or cdb instead of drwtsn32 to generate a
- vi命令
- memset的使用
- 突然想总结自己
- IXWebHosting优惠码/优惠链接
- 关于 GDI PS_INSIDEFRAME
- Windows Phone 7 开发 31 日谈——第2日:页面导航
- $(addprefix PREFIX,NAMES…)
- 专门替中国人写的英语语法1
- Hello World!
- C#抓屏