在我的类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
的最后一个成员元素。它使用size = capacity = 0正确初始化。
没有什么花哨的结构:
struct SReportData
{
CPoint pos;
std::tstring text;
int fontType;
COLORREF color;
};
在m_data
中初始化CReport
后,我保存了其_Myend
指针的地址:
的 0x03D84500
当CTestInspector
中的成员m_testInspector
位于(CTestController
)时,该位置的数据断点会立即在&m_testInspector
的构造函数中点击:
的 0x03D84502 !
这会破坏_Myend
指针,导致capacity
中出现错误的CReport.m_data
(例如3014656)。
造成这种腐败的原因是什么?
其他信息:
CGenericReport
属于另一个DLL项目CReport
,将其移至同一个模块无济于事sizeof(SReportData)
= 44 std::tstring
是typedefed std::wstring
答案 0 :(得分:2)
不同的成员对齐/填充是问题所在。
我观察到,在两个模块中,CGenericReport
的大小不同:136与134,同时包含相同的头文件。
在一种情况下,m_defaultCX
成员直接位于2字节成员m_dmOrient
之后,而在另一个模块中,包含2个字节以填充到8字节对齐。
然后,我在 C / C ++中的选项卡代码生成中检查了项目属性(/Zp, Struct Member Alignment >中的对齐设置)。两者都设置为默认(根据文档,= 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)
在另一个标头的末尾使用,它覆盖了项目设置并导致了这种行为。
删除它让我摆脱了这个麻烦。现在CGenericReport
的打包对齐对于每个模块都是相同的。