C语言,在利用struct进行数据封装时,经常会使用memset(this,0,sizeof(*this))来初始化。而C++中,有时候也会用到struct,在利用memset进行初始化时,非常容易踩坑,有些地方需要注意。
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;
---------------------
#include <iostream> #include <string.h> using namespace std; int main() { struct Test { int a; string b;
~Test(){cout<<"++++++++++++++++"<<endl;} }; Test test; memset(&test,0, sizeof(test)); return -1; }
~/learing/6-6# ./memset
++++++++++++++++
为毛没有 crash掉啊 !!!!!!!!!!!!!!
程序在第12行创建test 对象,在程序执行完后会自动执行 test的析构。但是,在析构到test的string成员 b 的时候,由于b的内存被memset破坏,因此不能正常析构,从而导致crash。