ZeroMemory和memset的区别
摘自百度百科,保存为学习使用
ZeroMemory,是美国微软公司的软件开发包SDK中的一个宏。 其作用是用0来填充一块内存区域。
声明
void ZeroMemory( PVOID Destination,SIZE_T Length );
参数
Destination :指向一块准备用0来填充的内存区域的开始地址。
Length :准备用0来填充的内存区域的大小,按字节来计算。
返回值
无
作用
ZeroMemory只是将指定的内存块清零。
使用结构前清零,而不让结构的成员数值具有不确定性,是一个好的编程习惯。
ZeroMemory和memset的区别:
1、ZeroMemory是微软的SDK提供的,memset是属于C Run-time Library提供的。因此ZeroMemory只能用于Windows系统,而memset还可用于其他系统。
2、ZeroMemory是一个宏,只是用于把一段内存的内容置零,内部其实是用 memset实现的,而memset除了对内存进行清零操作,还可以将内存置成别的字符。
3、如果程序是Win32程序而且不想连接c运行时库,就用ZeroMemory;如果需要跨平台,就用memset。
所以,如果ZeroMemory和memset用于清零操作,其本质是一样的。
ZeroMemory和 “={0}”的区别:
1、ZeroMemory会将结构中所有字节置0,而“={0}”只会将成员置0,其中填充字节不变。
2、一个struct有构造函数或虚函数时,ZeroMemory可以编译通过,而“={0}”会产生编译错误。其中,“={0}”的编译错误起到了一定的保护作用,因为对一个有虚函数的对象使用ZeroMemory时,会将其虚函数的指针置0,这是非常危险的(调用虚函数时,空指针很可能引起程序崩溃)。
struct SPerson
{char c;float s;};
class CTestVirtual
{public:
CTestVirtual(){}
/// 虚函数
virtual int Draw()
{return ;}
int a;
};
int main(int argc, char* argv[])
{
char sztmp[];
/// 安全操作
ZeroMemory(sztmp, sizeof(sztmp));
/// 安全操作
SPerson sTest = {};
int i = sizeof(SPerson);
//// 会引起编译错误!
//CTestVirtual otv = {0};
CTestVirtual tv;
/// 危险操作!
ZeroMemory(&tv, sizeof(tv));
/// 因为对象没有使用虚指针调用函数,所以程序运行到这里不会崩溃
tv.Draw();
/// 将对象地址赋给指针
CTestVirtual *pTv = &tv;
//虚函数的指针已经被清零,因此程序运行到这里会引起崩溃!
//错误信息:Unhandled exception at 0x004010b1 in Solution.exe:
//0xC0000005: Access violation reading location 0x00000000.
pTv->Draw();
return ;
}
因此,在windows平台下,数组或纯结构使用ZeroMemory是安全的,而类(class)就使用构造函数进行初始化,不要调用ZeroMemory。
另外,如果一个类的结构中包含STL模板(Vector、List、Map等等),那么使用ZeroMemory对这个类的对象中进行清零操作也会引起一系列的崩溃问题(指针指向内存错误、迭代器越界访问等)。所以,再次强烈建议:类(class)只使用构造函数进行初始化,不要调用ZeroMemory进行清零操作。
在Windows编程中,ZeroMemory的作用是用0来填充一块内存区域,主要是你填充一些数据结构时把它们填为0比较保险,因为很多默认的参数取值为NULL,操作系统会替你解决。
ZeroMemory和memset的区别的更多相关文章
- C++ 中 ZeroMemory、memset 危险需慎用
使用C/C++编程时,常使用ZeroMemory.memset或 “={0}”来对结构体对象进行初始化或清零.然而这三种方式都有各自的特点,使用时需谨慎,否则容易出现严重错误,本人今日解决一个导致宕机 ...
- 【转】bzero, memset ,setmem 区别
原文网址:http://blog.csdn.net/agathe/article/details/6066157 bzero 原型: extern void bzero(void *s, int n ...
- fill与memset的区别
fill 的头文件是<iostream> 命名空间是std: 在memset(a,0(-1),sizeof(a))全部初值定为0或-1时两者是没有多大区别; 但是在初值为其他值得时候就不同 ...
- strcpy、memcpy和memset的区别
strcpy 原型:extern char *strcpy(char *dest,char *src); 用法:#include <string.h> 功能:把src所指由NULL结束的字 ...
- bzero, memset ,setmem 区别【转】
本文转载自:http://chang6520.blog.163.com/blog/static/112665875201302843359715/ bzero 原型: extern void bzer ...
- fill和memset的区别
https://blog.csdn.net/xs18952904/article/details/75195412 memset只能初始化成为0或者-1,其他都要用fill来完成. #include& ...
- fill,fill-n,memset的区别
这里在网上搜集归纳了一个总结 memset函数 按照字节填充某字符 在头文件<string.h>中 因为memset函数按照字节填充,所以一般memset只能用来填充char型数组,(因为 ...
- C++中的memset、zeroMemory和={0}操作( 转)
使用C/C++编程时,常使用ZeroMemory.memset或 “={0}”来对结构体对象进行初始化或清零.然而这三种方式都有各自的特点,使用时需谨慎,否则容易出现严重错误,本人今日解决一个导致宕机 ...
- sizeof, strlen区别
strlen与sizeof的区别 .sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型. 该类型保证能容纳实现所建立的最大对象的字节大小. .size ...
随机推荐
- Redis在PHP中的基本使用案例
下载http://www.oschina.net/p/redis 解压后里面有:lib 源文件 .examples 例子.test测试 将lib目录拷贝到你的项目中,就可以开始你的predis操作了. ...
- URL参数带中文,后台接收乱码解决方案
1.前台中文参数用encodeURIComponent()进行编码,如: var textName= encodeURIComponent(name); 2.对整个URL用encodeURI()进行编 ...
- vue相关
勾三股四的vue+webpack实战:http://jiongks.name/blog/just... 用Vue构建一个Notes App:https://coligo.io/learn-vuex-. ...
- SRM566 1000pts
绍一的模拟赛题 [题意] 小Z养了$
- 织梦/dedecms 当文章转载时不需要设置图片水印的设置,取消’图片是否加水印‘的复选框,并且修改如下文件即可生效
当想添加水印是选中“图片是否加水印”复选框即可. 找到include/helpers/image.helper.php这个文件,在里面找到中的if( isset($GLOBALS['needwater ...
- 设置JVM内存溢出时快照转存HeapDump到文件
诊断内存溢出是一个有难度的事情,可以在生产环境试一试下面的参数,在发生内存溢出OutOfMemoryError时做HeapDump并保存到文件,然后分析该文件看是否能查到蛛丝马迹. set JAVA_ ...
- Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建
1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...
- [GIF] GIF Loop Coder - Animation Functions
Previous, we animate the item by passing an array to tell the start position and end position. To ma ...
- Java调用yahoo!API获取天气数据
先把代码复制上来,以后再做补充 package com.weather.test; import java.io.InputStream; import java.net.URL; import ja ...
- oracle 查看表属主和表空间sql
查看表空间 select * from user_tablespaces where table_name = 'TableName' 查看表属主 select Owner from all_ta ...