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

标签 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 的最后一个成员元素。它已正确初始化,大小 = 容量 = 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 后出现同样的问题
  • CGenericReportCReport 一样属于另一个 DLL 项目,将其移动到同一模块没有帮助
  • sizeof(SReportData) = 44
  • std::tstring 是类型定义的 std::wstring

最佳答案

不同的成员对齐/填充是问题所在。

我观察到,在两个模块中,CGenericReport 的大小不同:136 与 134,同时包含相同的头文件。

在一种情况下,m_defaultCX 成员直接位于 2 字节成员 m_dmOrient 之后,而在另一个模块中,包含 2 个字节以填充到 8 字节对齐。

然后我检查了项目属性中的对齐设置( /ZpC/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/

相关文章:

C++成员布局

c++ - 这种标准化适合摆动曲线吗?

c++ - 我可以获得正式而非实际模板参数的字符串表示形式吗?

c# - VS2012 + CRM 2011 : Microsoft. IdentityModel 引用错误

c++ - std::string 作为成员函数参数的奇怪行为

C++ 列表 : copying a local list in a member list

c++ - 在 Ubuntu 14.04 下与 `libopencv_highgui.so` 链接错误, `libtiff.so.5` 的奇怪结果

c++ - 如何在运行时检查对象是否派生自特定类?

c++ - Profiler 不显示我的代码

c++ - 为什么这个 C++ 片段可以编译(非 void 函数不返回值)