Discussion:
Heap Error Debugging with strange sizeof behavior
(too old to reply)
GaryGen
2009-11-19 18:51:37 UTC
Permalink
I am encountering a heap error in VC++ in VS2008. The problem appears
to be related to the allocation of member variables on the heap. I am
reporting the problem here in vc.debugger since there is an associated
Watch window glitch that appears to be related.

In the code snippet below, creating a new CTestObject2 results in a
heap error at certain heap addresses. I believe this is due to the
bool's in CTestObject2 being misaligned in some cases under the
default /Zp8.

The interesting thing here is that a sizeof(*this) in the CTestObject2
constructor will return 40 bytes, but if I do sizeof(*this) from the
watch window while stopped there, I get 34 bytes, which is what the
size would be with /Zp1 alignment. While this could be a Watch window
glitch, the behavior only appears when the heap error occurs.

If I do not call _heapchk, calls to set the member variables appear to
write different memory locations than calls to read the member
variables.

If I replace the bool's with BOOL's, the size is 40 bytes in both
cases and no heap exception occurs.

Note that I can only get this to occur in my production application.
Smaller test cases with the same compiler options are not reproducing
the behavior, even when the heap is allocated to match the original
addresses. In the test apps, sizeof(*this) always returns 40.

class CTestList : public CTypedPtrList<CPtrList,void*>
{
public:
CTestList() {};
};

class CTestObject2
{
public:
CTestObject2();
bool m_bool_1;
void* m_ptr_1;
bool m_bool_2;
CTestList m_list_1;
};

CTestObject2::CTestObject2()
{
ASSERT(_heapchk() == _HEAPOK);
}

CTestObject2 size=40 loc=025E3ED8 to 025E4518
.m_bool_1 size=1 loc=025E3ED8 to 025E3ED8
.m_ptr_1 size=4 loc=025E3EDC to 025E3EDF
.m_bool_2 size=1 loc=025E3EE0 to 025E3EE0
.m_list_1 size=28 loc=025E3EE4 to 025E3EFF
HEAP[TradingSolutions.exe]: Heap block at 025E3EB0 modified at
025E3EFE past requested size of 46
Scot Brennecke
2009-11-23 10:01:24 UTC
Permalink
Post by GaryGen
I am encountering a heap error in VC++ in VS2008. The problem appears
to be related to the allocation of member variables on the heap. I am
reporting the problem here in vc.debugger since there is an associated
Watch window glitch that appears to be related.
In the code snippet below, creating a new CTestObject2 results in a
heap error at certain heap addresses. I believe this is due to the
bool's in CTestObject2 being misaligned in some cases under the
default /Zp8.
The interesting thing here is that a sizeof(*this) in the CTestObject2
constructor will return 40 bytes, but if I do sizeof(*this) from the
watch window while stopped there, I get 34 bytes, which is what the
size would be with /Zp1 alignment. While this could be a Watch window
glitch, the behavior only appears when the heap error occurs.
If I do not call _heapchk, calls to set the member variables appear to
write different memory locations than calls to read the member
variables.
If I replace the bool's with BOOL's, the size is 40 bytes in both
cases and no heap exception occurs.
Note that I can only get this to occur in my production application.
Smaller test cases with the same compiler options are not reproducing
the behavior, even when the heap is allocated to match the original
addresses. In the test apps, sizeof(*this) always returns 40.
class CTestList : public CTypedPtrList<CPtrList,void*>
{
CTestList() {};
};
class CTestObject2
{
CTestObject2();
bool m_bool_1;
void* m_ptr_1;
bool m_bool_2;
CTestList m_list_1;
};
CTestObject2::CTestObject2()
{
ASSERT(_heapchk() == _HEAPOK);
}
CTestObject2 size=40 loc=025E3ED8 to 025E4518
.m_bool_1 size=1 loc=025E3ED8 to 025E3ED8
.m_ptr_1 size=4 loc=025E3EDC to 025E3EDF
.m_bool_2 size=1 loc=025E3EE0 to 025E3EE0
.m_list_1 size=28 loc=025E3EE4 to 025E3EFF
HEAP[TradingSolutions.exe]: Heap block at 025E3EB0 modified at
025E3EFE past requested size of 46
This article is focused on finding ODR violations, but it reveals some
neat tricks about figuring out class layout mysteries:
Visual C++ Team Blog : Diagnosing Hidden ODR Violations in Visual C++
(and fixing LNK2022):
http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx
GaryGen
2009-12-29 21:46:27 UTC
Permalink
Post by Scot Brennecke
This article is focused on finding ODR violations, but it reveals some
Visual C++ Team Blog : Diagnosing Hidden ODR Violations in Visual C++
(and fixing LNK2022):http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr...- Hide quoted text -
Thanks! It took a while for me to figure out how to apply those
techniques properly, but it turned out to be exactly the debugging
information I needed. Evidently, most references to the structure were
pack=8, but some were pack=1. Still need to figure out where the
difference is, but at least the answer is rooted in logic again. :)
Loading...