C++构造函数使用memset初始化可能导致的问题

今天在写代码的时候突然遇到一个中断问题,但是光看代码根本发现不了错误,代码大概类似于:

typedef struct MemsetTest
{
	int     year;
	map<int,string> m_map;

	MemsetTest()
	{
		memset(this , 0 , sizeof(MemsetTest));
	}
}MemsetTest;


int Main()
{
	MemsetTest tTest;
	tTest.year = 2020;
	tTest.m_map[5] = "5";
}

其中为map添加值那一行会报错。

遇到这个问题之后看代码是在想不出问题在哪,然后我就把源代码中MemsetTest的结构体给复制到了一个新的工程中测试,但是还是会爆错,于是我试着删除了MemsetTest的m_map变量,在测试是可以正常运行的;但是变得更迷惑了,map用了没有一千也有八百次了,为什么这里会死机?就继续删代码一点点测试,最后删到发现有memset与map同时存在就会出问题;在网上一搜索了解到问题果然出现在memset上:memset()函数将对象的所有内存都初始化为0,这在初始化的类是一个POD类型(Plain Old Data)时是没有问题的,因为POD类型的二进制内容可以随便复制、移动、重置而不会改变POD类型对象的值。ConfigSettings成员都是POD类型(int,char,float…),而且ConfigSettings类既不存在虚继承也不存在虚函数,所以可以对ConfigSettings使用memset()函数进行初始化。但是因为我在MemsetTest中加入了map类型的成员变量,就导致MemsetTest不再是一个POD类型结构,所以当使用memset()函数进行初始化时会对对象造成破坏,map底层是红黑树,其中必然包括各种指针,当使用memeset将对象所有内存初始化为0的时候,map中的各种指针必然就变成了null_ptr,整个结构已经被完全破坏了,所以会后面对map进行操作的时候就会出现崩溃。

 

最后解决办法

  1. 重新写MemsetTest的构造函数,不再使用memset()函数初始化对象。
  2. 将成员变量map设置为static类型,可以避免在memset()时被破坏.

另外以后一定要注意构造函数初始化尽量不要直接使用memset,因为就算你写的时候是一个POD结构,但随着时间的流逝后续其他人维护就可能添加指针等,到时他如果不了解这个问题就又会困住他好久。

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值