关于struct 结构体与memset的狗血教训
在利用struct进行数据封装时,经常会使用memset(this,0,sizeof(*this))来初始化。而C++中,有时候也会用到struct,在利用memset进行初始化时,非常容易踩坑,可谓是菜鸟杀手!
看段代码:

struct QuoteField
{
	//tag==10028 报价时间
	std::string SCQuoteTime;
	//tag==132 
	double bidPx_s; 
	//tag==133 
	double offerPx_s;
	//tag==134
	int bidsize;
	//tag==135
	int offersize;
};
{
	QuoteField  quoteField;
	memset("eField, 0, sizeof(QuoteField));
	printf("这是一个狗血教训!");
	quoteField.SCQuoteTime="2020-02-30 16:16:16";
	quoteField.offersize=100;
	quoteField.offerPx_s=3.1415;
}

这段代码是在windows下用vs2017编译运行,都没有问题;但是在Linux下运行,就会产生致命错误导致crash;quoteField.SCQuoteTime无法被赋值,被memset破坏掉了什么。如果注释掉quoteField.SCQuoteTime=“2020-02-30 16:16:16”;后续的赋值又是正确的,比较疑惑;仔细一想,突然想到string的本质也是指针啊~,所以应该是memset破坏了string指针。

C++利用memset初始化struct注意点

1. memset 是按字节对内存块进行初始化的函数,用来给某一块内存空间进行赋值的;

2. memset 作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法;

3. 成员变量可以是简单的内置类型(short、int、long、char、float、double);

4. memset函数不能将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同):

     memset是逐字节进行初始化,比如对整型数进行初始化,int是32位的共四个字节,每个字节设置为n,则

     如果n=1,1为00000001 00000001 00000001 00000001,转为十进制数是1+1*2^8+1*2^16+1*2^24=16843009,而不是1;

     如果n=0,0为 00000000 00000000 00000000 00000000,转化为十进制为0;

     如果n=-1,-1为 11111111 11111111 11111111 11111111(原码的反码的补码),转化后为-1。    

5. 类中含有C++类型的对象(string, list, set, map等)时,千万不要使用memset进行初始化,因为会破坏对象的内存,可用构造函数来实现;

6. 类含有虚函数表时,初始化会破坏虚函数表,后续对虚函数的调用都将出现异常;

7. 类含有指针时,初始化时,并不会初始化指针指向对象的值,而会把该指针设置为0;

这例子直接对应上了第5点和第7点了。
改一下struct的初始化方式吧~

struct QuoteField
{
	//tag==10028 报价时间
	std::string SCQuoteTime;
	//tag==132 
	double bidPx_s; 
	//tag==133 
	double offerPx_s;
	//tag==134
	int bidsize;
	//tag==135
	int offersize;

	QuoteField() 
	{
		memset(&bidPx_s, 0, sizeof(offerPx_s));
		memset(&offerPx_s, 0, sizeof(offerPx_s));
		bidsize = 0;
		offersize = 0;
	}
};