成员因以下成员的初始化而损坏

时间:2014-03-07 10:56:38

标签: c++ visual-studio-2012 member memory-corruption

在我的类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_dataCReport的最后一个成员元素。它使用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)。

造成这种腐败的原因是什么?

其他信息:

  • 清洁/重建无济于事
  • 我正在使用MFC和Unicode
  • 升级到Visual Studio 2013后的相同问题
  • CGenericReport属于另一个DLL项目CReport,将其移至同一个模块无济于事
  • sizeof(SReportData) = 44
  • std::tstring是typedefed std::wstring

1 个答案:

答案 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的打包对齐对于每个模块都是相同的。