new object causes corruption on the heap
I've been struggling with a heap corruption problem for a few days. I was first warned by the vs 2005 debugger that I may have corrupted the heap, after deleting an object I had previously new'ed. Doing research on this problem led me to gflags and the page heap setting. After enabling this setting for my particular image, it supposedly pointed me to the line that is actually causing the corruption.
Gflags identified the constructor for the object in question as the culprit. The object derives as follows:
class POPUPS_EXPORT MLUNumber : public MLUBase
{
...
}
class POPUPS_EXPORT MLUBase : public BusinessLogicUnit
{
...
}
I can instantiate an MLUNumber in a separate thread, and no heap corruption occurs.
I can instantiate a different class, that also inherits from MLUBase, that does not cause heap corruption.
The access violation raises due to the corruption occurs on the opening brace of the constructor, which appears to be because of the implicit initializing of the object (?).
The base class constructor (MLUBase) successfully finishes.
From digging with the memory window in vs 2005, it appears 开发者_如何学编程that there was not enough space allocated for the actual object. My guess is that enough was allocated for the base class only.
The line causing the fault:
BusinessLogicUnit* biz = new MLUNumber();
I'm hoping for either a reason that might cause this, or another troubleshooting step to follow.
Unfortunately, with the information given, it's not possible to definitively diagnose the problem.
Some things you may want to check:
- Make sure BusinessLogicUnit has a virtual destructor. When
delete
ing objects through a base pointer, a virtual destructor must be present in the base class for the subclass to be properly destructed. - Make sure you're building all source files with the same preprocessor flags and compiler options. A difference in flags (perhaps between debug/release flags?) could result in a change in structure size, and thus an inconsistency between sizes reported in different source files.
- It's possible for some types of heap corruption to go undetected, even with your gflags settings. Audit your other heap uses to try to find the source of your issues as well. Ideally you should put together a minimal test case that will reliably crash, but with a minimum amount of activity, so you can narrow down the cause.
- Try a clean solution and rebuild; I've occasionally seen timestamps getting screwed up, and an old object file can get in with an out-of-date structure definition. Worth checking at least :)
BusinessLogicUnit* biz = new MLUNumber();
How do you delete the memory? Using the base-class pointer? Have you made the destructor of BusinessLogicUnit
virtual? It must be virtual
.
class BusinessLogicUnit
{
public:
//..
virtual ~BusinessLogicUnit(); //it must be virtual!
};
Otherwise deleting the derived class object through the base-class pointer invokes undefined behavior as per the C++ Standard.
BusinessLogicUnit is not an MLUNumber. Why would you allocate this way? Instead BusinessLogicUnit* biz = new BusinessLogicUnit();
Or maybe you do something like this?
struct A
{
SomeType & m_param;
A(SomeType & param) : m_param(param)
{
...use m_param here...
}
};
A a(SomeType()); // passing a temporary by reference
Then that's undefined behaviour, because the referenced temporary dies right after m_param(param)
happens..
I agree with bdonlan that there isn't enough information yet to figure out what's wrong. There are a lot of good suggestions here, but just guessing possible reasons why an application is crashing is not a smart way to root cause an issue.
You've done the right thing by enabling instrumentation (pageheap) to help you narrow down the problem. I would continue down this path by finding out exactly which memory address is causing the access violation (and where the address came from).
精彩评论