使用C/C++编程时,常使用ZeroMemory、memset或 “={0}”来对结构体对象进行初始化或清零。然而这三种方式都有各自的特点,使用时需谨慎,否则容易出现严重错误,本人今日解决一个导致宕机的bug,查了几小时,才发现是由同事乱用ZeroMemory所致。于是搜集资料,撰此文以共勉。

memset

void *memset(void *s,int ch,size_t n); 是由C Run-time Library提供的提供的函数,作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。由于是语言层面提供,所以可跨平台使用。参考:http://www.cplusplus.com/reference/cstring/memset/
示例:

  1. char str[] = "almost every programmer should know memset!";
  2. memset (str,'-',6);
  3. puts (str);

输出:

  1. ------ every programmer should know memset!

ZeroMemory

ZeroMemory是美国微软公司的软件开发包SDK中的一个宏。 其作用是用0来填充一块内存区域。定义式如下

  1. #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
  2. #define ZeroMemory RtlZeroMemory

由此可见:

  1. ZeroMemory实际是用memset实现的。
  2. ZeroMemory只能用于windows平台。

注意:

ZeroMemory和memset且于清零时,会将结构中所有字节置0,如果结构体中有虚函数或结构体成员中有虚函数,则会将虚函数指针置0,如果后续程序调用虚函数,空指针很可能导致程序崩溃!

因此,有虚函数或成员中有虚函数的结构体初始化,一定要用构造函数来完成。

另外,如果一个类的结构中包含STL模板(Vector、List、Map等等),那么使用ZeroMemory对这个类的对象中进行清零操作也会引起一系列的崩溃问题(指针指向内存错误、迭代器越界访问等)。所以,再次强烈建议:类(class)只使用构造函数进行初始化,不要调用ZeroMemory进行清零操作。

示例:

  1. #include "stdafx.h"
  2. #include <Windows.h>
  3. class Car
  4. {
  5. public:
  6. virtual void Run(){}
  7. private:
  8. int m_speed;
  9. };
  10. struct  SRace
  11. {
  12. Car car;
  13. int dirver;
  14. };
  15. int _tmain(int argc, _TCHAR* argv[])
  16. {
  17. SRace race;
  18. ZeroMemory(&race,sizeof(race));
  19. // 没通过虚表指针调用,没事
  20. race.car.Run();
  21. Car *pCar = &race.car;
  22. // __vfptr = 0x00000000,崩溃
  23. pCar->Run();
  24. return 0;
  25. }

={0}

={0}操作是结构体和数组的一种初始化方式,它是将结构体中基本类型变量赋默认值,当结构体中有非基本类型(例如类对象)时,会编译错误,这也是一种保护。

C++ 中 ZeroMemory、memset 危险需慎用的更多相关文章

  1. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  2. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  3. VB.NET中网络编程所需组件WinHTTP的添加

    VB.NET中网络编程所需组件: WinHTTP组件:项目-->添加引用-->COM选项卡-->Microsoft WinHTTP Services,version 5.1--> ...

  4. memcached—向memcached中保存Java实体需注意的问题

    今天以代码实例的形式总结一下向memcached中保存Java实体需注意的问题: memcached工具类代码: package com.ghj.packageoftool; import java. ...

  5. C++中的memset、zeroMemory和={0}操作( 转)

    使用C/C++编程时,常使用ZeroMemory.memset或 “={0}”来对结构体对象进行初始化或清零.然而这三种方式都有各自的特点,使用时需谨慎,否则容易出现严重错误,本人今日解决一个导致宕机 ...

  6. 面试中关于Java你所需知道的的一切

    本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺. 1. Java中的原始数据类型都有哪些, ...

  7. [转]C/C++中的memset

    http://blog.csdn.net/songuooo/article/details/7819790 1. 需要的头文件 C中为<memory.h> 或 <string.h&g ...

  8. 关于write solid code中的memset

    文中说明memset可以通过操作整形以加速程序执行速度,这一点值得肯定,问题在于unicore或arm中协处理器有地址访问对齐检查,如果我们如此操作,编译器最终使用str指令来完成,那么当地址未对齐时 ...

  9. android布局中使用include及需注意点

    在android布局中,使用include,将另一个xml文件引入,可作为布局的一部分,但在使用include时,需注意以下问题: 一.使用include引入 如现有标题栏布局block_header ...

随机推荐

  1. leetcode 374

    这个题目很简单,但是要注意细节和对题目的理解,一开始我把guess函数的作用理解错了,第一版代码长这样: int guessNumber(int n) { ; int high = n; while( ...

  2. 献给初学者:谈谈如何学习Linux操作系统

    本文出自 “技术成就梦想” 博客,请务必保留此出处http://ixdba.blog.51cto.com/2895551/569329. 为了能把这篇不错的文章分享给大家.所以请允许我暂时用原创的形式 ...

  3. 产品Backlog

    产品BACKLOG ID Name Imp Est How to demo Notes 1 界面(首页.订单.资料) 50 2 进入界面,选择需要的界面 使用分栏界面 2 首页里的功能按钮 40 6 ...

  4. gradle手工搭建java项目搭建

    1. 安装gradle. 下载http://services.gradle.org/distributions/gradle-1.9-all.zip,解压至/usr/local/目录下. 设置环境变量 ...

  5. 转 java中的session

    书中讲:以下情况,Session结束生命周期,Servlet容器将Session所占资源释放:1.客户端关闭浏览器2.Session过期3.服务器端调用了HttpSession的invalidate( ...

  6. maven+Jenkins学习小记

    jenkins配置方法1,tomcat下载,解压,切换到bin目录,配置环境变量,地址为catalina.bat文件夹下,也就是bin目录,再配置path变量2,启动tomcat,dos命令,cata ...

  7. 基于.NET的微软ORM框架视频教程(Entity Framework技术)

    基于.NET的微软ORM框架视频教程(Entity Framework技术) 第一讲  ORM映射 第二讲 初识EntifyFramework框架 第三讲 LINQ表达式查询 第四讲 LINQ方法查询 ...

  8. 第 十一 天 Flagmeng 和动画

    1.flagment 的使用,生命周期. 传递数据. 2. 基本动画的使用. 3. 对话框的使用. 4.样式和主题.

  9. 遗传算法在JobShop中的应用研究(part 2:编码)

    编码 在上一篇博客中我们讨论了车间调度问题的编码,具体说就是根据工件的个数和每个工件的工序数来生成12122这样的数字排列,具体的说一个工件包含多少道工序,那么这个工件的编号就出现多少次.从12122 ...

  10. SpringMVC控制器与视图的数据交换

    1,先创建spring的主配置文件(applicationContaxt.xml如果写在WEB-INF下,就不用配置context了,就是不用告诉它路径了,WEB-INF会自动加载的),由监听器负责加 ...