在我的类CTestController
初始化期间,成员std::vector被损坏,我不知道是什么导致了这种行为。
情况如下:
class TestController
{
// ...
CReport m_report;
CTestInspector m_testInspector;
// ...
}
这些成员在CTestController
的构造函数中隐式实例化。
class CReport : public CGenericReport
{
// ...
std::vector<SReportData> m_data;
}
和
class CGenericReport
{
// ...
COLORREF m_bgColor;
const short m_dmOrient;
long m_defaultCX;
long m_defaultCY;
CWnd m_wnd;
}
m_data
是CReport
的最后一个成员元素。它已正确初始化,大小 = 容量 = 0。
结构没什么特别的:
struct SReportData
{
CPoint pos;
std::tstring text;
int fontType;
COLORREF color;
};
在CReport
中初始化m_data
后,我保存其_Myend
指针的地址:
0x03D84500
当 CTestController
中的成员 m_testInspector
位于 (&m_testInspector
):
0x03D84502!
这会损坏 _Myend
指针,导致 CReport.m_data
中出现错误的容量
(例如 3014656)。
造成这种损坏的原因是什么?
其他信息:
- 清理/重建没有帮助
- 我正在使用 MFC 和 Unicode
- 升级到 Visual Studio 2013 后出现同样的问题
CGenericReport
与CReport
一样属于另一个 DLL 项目,将其移动到同一模块没有帮助sizeof(SReportData)
= 44std::tstring
是类型定义的std::wstring
最佳答案
不同的成员对齐/填充是问题所在。
我观察到,在两个模块中,CGenericReport
的大小不同:136 与 134,同时包含相同的头文件。
在一种情况下,m_defaultCX
成员直接位于 2 字节成员 m_dmOrient
之后,而在另一个模块中,包含 2 个字节以填充到 8 字节对齐。
然后我检查了项目属性中的对齐设置( /Zp ,C/C++ 选项卡中的结构成员对齐 )。两者均设置为默认(根据文档= 8 字节)。
但是,当我插入
#pragma pack(show)
进入CGenericReport
头文件,编译器报告
warning C4810: value of pragma pack(show) == 8
...
warning C4810: value of pragma pack(show) == 1
此地点的顺序不同。
最后我发现了一个#pragma pack指令
#pragma pack(1)
在另一个 header 的末尾使用,该 header 覆盖了项目设置并导致了此行为。
删除它让我摆脱了这个麻烦。现在,每个模块的 CGenericReport
的打包对齐都是相同的。
关于c++ - 成员因以下成员的初始化而损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22248170/