Pregunta

During initialization of my class CTestController a member std::vector gets corrupted and I have no idea what causes this behavior.

The situation is as follows:

class TestController
{
    // ...   
    CReport m_report;
    CTestInspector m_testInspector;
    // ...
}

These members get implicitly instantiated in the constructor of CTestController.

class CReport : public CGenericReport
{
    // ...
    std::vector<SReportData> m_data;
}

and

class CGenericReport
{
    // ...
    COLORREF m_bgColor;
    const short m_dmOrient;
    long m_defaultCX;
    long m_defaultCY;
    CWnd m_wnd;
}

m_data is the last member element of CReport. It gets properly initialized with size = capacity = 0.

Nothing fancy with the struct:

struct SReportData
{
    CPoint pos;
    std::tstring text;
    int fontType;
    COLORREF color;
};

After initialization of m_data in CReport I save the address of its _Myend pointer:
0x03D84500
A data breakpoint on that location gets immediately hit in the constructor of CTestInspector, when the member m_testInspector in CTestController is located at (&m_testInspector):
0x03D84502!
This corrupts the _Myend pointer resulting in an erroneous capacity (eg. 3014656) in CReport.m_data.

What could be the reason for this corruption?

Additional information:

  • Clean/rebuild does not help
  • I'm using MFC and Unicode
  • Same problem after upgrading to Visual Studio 2013
  • CGenericReport belongs to another DLL project as CReport, moving it to the same module doesn't help
  • sizeof(SReportData) = 44
  • std::tstring is typedefed std::wstring
¿Fue útil?

Solución

Different Member Alignment/Padding was the problem.

I observed that across two modules the size of CGenericReport was different: 136 vs. 134 while including the same header file.

In one case the m_defaultCX member was located directly after the 2 byte member m_dmOrient while in the other module 2 bytes were included to pad to 8 byte alignment.

Then I checked the alignment settings in the project properties (/Zp, Struct Member Alignment in tab Code Generation in C/C++). Both were set to Default (= 8 byte according to the documentation).
However, when I inserted a

#pragma pack(show)

into the CGenericReport header file, the compiler reported

warning C4810: value of pragma pack(show) == 8
...
warning C4810: value of pragma pack(show) == 1

for this spot in varying order.

Finally I cotton on to a #pragma pack directive

#pragma pack(1)

being used at the end of another header that overrode the project settings and caused this behavior. Removing it released me from this trouble. Now the packing alignment of CGenericReport is the same for every module.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top