C++ POD与结构体声明
来源:互联网 发布:工程决算软件下载 编辑:程序博客网 时间:2024/05/22 11:31
- struct MyStruct
- {
- int i;
- wstring str;
- vector<wstring> strs;
- };
上面的结构休定义有问题吗?理论上说没有,但在某些情况下就有问题了。如下用法:
- MyStruct *pMy = new MyStruct();
- memset(pMy, 0, sizeof(MyStruct));
- pMy->i = 100;
- pMy->str = L"leehong";
- // Here will crash, vector is not POD, so memset() function or ZeroMemory macro
- // do not know how to initialize the member, or it will lead some infos of pstr member
- // lost and crash when access. pMy->pstr.push_back(L"One");
如果这样用的话,在Debug下运行没有问题,但在Release下运行,就会在push_back处Crash。这是为什么呢?这就引出下面要讲的POD了。
什么是POD
POD(Plain Old Data)指的是能够像C语言中的结构体那样进行处理的一种数据类型,比如能够使用memcpy()来复制内存,使用memset()进行初始化等。
在C++ 98标准中,POD实际上是受限于结构体定义中的语言特性而定义的。
- struct S { int a; }; //S就是一个POD
- struct SS { int a; SS(int aa) : a(aa) { } }; // SS就不是POD了
- struct SSS { virtual void f(); };
在C++0x中,POD被定义为可以简简单单复制的,类型普通的,并且拥有可以应对多种POD原先就能支持的操作的标准变量地址布局(?)。POD的定义和以前差不多:
1)如果你所有的成员变量和基类都是POD,那么这个类型就是POD。
2)POD应当满足以下要求,
新标准对POD最大的影响就是,对于拥有不会影响数据分配布局的构造函数的数据结构,也可以算作是POD。
关于POD详细信息,请参考官方文档:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2294.html
Crash原因分析
回到最上面举的那个例子,结构体初始化时,首先会调用它自动生成的默认构造函数,同时也会调用vector<wstring>的构造函数为pstr成员生成一块内存。然后我们都知道,使用结构体一般都会用memset 或 ZeroMemory函数来把结构体清成0,那么当我们调用ZeroMemory后,之前为pstr生成的内存就变成了0,这样当在后面再访问这个成员时,就会导致Crash。
所以一般情况下在结构体中不要定义一些复杂的数据类型,如果无法避免,就声明这种类型的指针,因为指针肯定是一个POD的数据。
解决方法
1)上面的那种方法可以把pstr换成指针类型,也就是vector<wstring>* 在调用ZeroMemory后,再对这个变量分配内存。
2)为这个结构体写构造函数,在这个构造函数里面进行初始化,在使用时永远不要调用ZeroMemory,这样的话,struct就实际上跟class的用法一样了。
- C++ POD与结构体声明
- C++ POD与结构体声明
- C++ POD与结构体声明
- C语言结构体声明
- C结构体向前声明一种用法
- 结构体变量声明与赋值
- 结构体变量声明与赋值初始化
- 单链表的结构体定义与声明
- 单链表的结构体定义与声明
- 结构体的声明与定义
- C语言头文件组织与包含原则(函数指针和结构体的前项声明)
- C语言 struct结构体的变量声明加冒号
- C语言中结构体的声明方式
- C语言结构体类型声明和定义标准形式
- c语言结构体的声明和初步操作
- C语言 struct结构体的变量声明加冒号
- JS 声明结构体
- 结构体声明-struct
- Error creating bean with name 'txManager' defined in file
- 树形动态规划(树状DP)小结
- IOS 中viewDidLoad和loadView的关系,个人认为比较容易理解的
- 欢迎使用CSDN-markdown编辑器
- JAVA 关于rotate()以后坐标以及显示的问题
- C++ POD与结构体声明
- Jsoup+HttpClient获取新浪新闻数据
- 就这样,你与35W擦肩而过
- C语言笔记之数据类型(二)
- [算法]由日期格式函数产生的若干思考 y * 512 + m * 32 + d
- 秒懂单链表及其反转(reverse)
- 黑马程序员-IO流
- JavaWeb 服务启动时,在后台启动加载一个线程
- spring security详解