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

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

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

输出:

------ every programmer should know memset!

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

#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
#define ZeroMemory RtlZeroMemory

由此可见:

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

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

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

#include <iostream>
#include <Windows.h>class Car
{public:virtual void Run() {}void print() { puts("hello world"); }
private:int m_speed;
};
struct  SRace
{Car car;int dirver;
};int main(void)
{char str[] = "almost every programmer should know memset!";memset(str, '-', 6);puts(str);SRace race;race.car.print();memset(&race, 0, sizeof(SRace));// ZeroMemory(&race, sizeof(race));race.car.print();// 没通过虚表指针调用,没事race.car.Run();Car* pCar = &race.car;// __vfptr = 0x00000000,崩溃pCar->Run();return 0;
}

类的多个对象共享类的函数,类中函数所占空间加载时将其放到了代码区,每个类的对象都会分配其非静态成员变量空间,我们可以根据对象中成员变量的不同取值确定对象的不同状态,sizeof(class_object)就是返回对象所占空间的大小。
细化一下:
代码区存储程序的代码
数据区存放全局变量和静态变量,与常量 其实可以细化为全局/静态数据区与常量数据区
栈中存放局部变量与传来的参数
堆是动态分配使用的。
类在内存里的数据连续存储,基本上就是存几个非静态成员变量与虚函数表指针(如果存在)

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

C++ 中 ZeroMemory、memset相关推荐

  1. ZeroMemory memset 等清零的用法(笔记)

    ZeroMemory memset 等清零的用法(笔记) (1)函数的原型和参数的介绍 ZeroMemory函数 void ZeroMemory( PVOID Destination,SIZE_T L ...

  2. ZeroMemory memset 等清零的用法

     ZeroMemory memset 等清零的用法(笔记) (1)函数的原型和参数的介绍 ZeroMemory函数 void ZeroMemory( PVOID Destination,SIZE_T ...

  3. C++对象模型4——多重继承的对象内存模型、vptr与vtbl的创建与重置的时机、不要在含有虚函数的类的构造函数中调用memset

    一.多重继承的对象内存模型 class Base1 { public:virtual void f() {cout << "base1::f()" << e ...

  4. c语言中memset_C中的memset()

    c语言中memset The memset() function in C is used to set blocks of memory with a particular value. C语言中的 ...

  5. C++ 中 ZeroMemory、memset 危险需慎用

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

  6. 转: C++ 中 ZeroMemory、memset 易内存出错

    转自:https://blog.csdn.net/tjunxin/article/details/8540259 https://blog.csdn.net/my_business/article/d ...

  7. Zeromemory memset

    1. void ZeroMemory( PVOID Destination, SIZE_T Length); Destination :指向一块准备用0来填充的内存区域的开始地址. Length :准 ...

  8. 构造函数中慎用memset

    写了一个小程序,工作时会跑一个大循环,在运行时发现有严重的内存泄露,内存不停增长. 经过几次复查,终于找出问题所在,代码结构大概如下: struct myobj { myobj() { memset( ...

  9. C++中的memset函数

    memsetmemset是计算机中C/C++语言初始化函数.作用是将某一块内存中的内容全部设置为指定的值,在数组初始化上非常简便,其通式如下: memset(数组名,数组中每一个元素要定义的初始值,s ...

最新文章

  1. MySQL-一条sql语句的执行顺序
  2. [剑指offer]面试题13:在O(1)时间删除链表结点
  3. HTTP get post put delte等
  4. mysql 求bit 某位为1_mysql按位的索引判断值是否为1
  5. 工作309:selectaccount方法接收值
  6. mysql修改文件名_SQL语句实现附加数据库,可以改数据库物理文件名
  7. plesk 打不开php,如何在 Plesk 中管理 PHP
  8. Visual Basic6.0下载及安装
  9. 自动驾驶路径规划——A*(Astar)算法
  10. win7 变wifi热点
  11. java deflate,java.util.zip.Deflater.deflate(byte[] b, int off, int len)方法示例
  12. oracle图书操作、sql语句查询+授权、视图、索引、表操作
  13. 再谈计算机编程的学习
  14. 搭建Openstack环境以及Openstack认证服务
  15. linux hosts文件的修改------利用root权限来vim /etc/hosts
  16. CSP202109-4 收集卡牌
  17. gem 安装oxidized-web报错:checking for -licui18n... no处理
  18. 在种子轮中,如何区分风险投资、种子投资和天使投资?
  19. Numpy:关于flatten的理解
  20. 使用计算机配置路由器,用命令配置路由器基础(

热门文章

  1. Java的System.getProperty()方法获取信息的用法
  2. Oracle故障案例 | 19C动态监听无法注册实例的处理
  3. Springboot整合activiti(最详细版)
  4. ai图片怎么把图中的字改掉_ai cs6 隐藏透视网格和ai怎么把图片中的文字抠出来...
  5. 弘辽科技:拼多多商家如何自己提升销量?提升销量需要注意什么?
  6. 产业分析:2022广东省产业全景
  7. python(moviepy ) mp4视频拼接截取
  8. Memcached 与Redis缓存服务器介绍
  9. 监听剪切板内容,解决复制粘贴内容格式错乱
  10. java eden s0 s1_不是吧!做了两年java还没弄懂JVM堆?进来看看你就明白了