Discussion:
Class instance internal destruction sequence?
(too old to reply)
Chris
2010-04-30 01:59:01 UTC
Permalink
Hi there,

A class usually has non-static member method(s). When an instance of such
class gets destroyed, is its non-static member method destroyed before its
destructor is called? The reason I raised this question is that I faced the
following problem in debug build:
I have a class which has a member data of std::map type. The map member data
has entries that are pointers to the member methods of the class, like
typedef void (MyClass::*ActionMethodType)(const char*);
std::map<string, ActionMethodType> actions;
typedef std::map<string, ActionMethodType>::iterator actionIt;
In the class destructor, actions.clear() is called. This call inside the
destructor at runtime led to an access violation inside _Orphan_ptr of
std::xtree via the std::map data member. However, calling the actions.clear()
elsewhere didn't have such access violation problem. This led me to wonder
what destruction order between member methods and destructor of a class
instance.


Regards
Chris
Scott McPhillips [MVP]
2010-04-30 02:26:29 UTC
Permalink
Post by Chris
Hi there,
A class usually has non-static member method(s). When an instance of such
class gets destroyed, is its non-static member method destroyed before its
destructor is called? The reason I raised this question is that I faced the
I have a class which has a member data of std::map type. The map member data
has entries that are pointers to the member methods of the class, like
typedef void (MyClass::*ActionMethodType)(const char*);
std::map<string, ActionMethodType> actions;
typedef std::map<string, ActionMethodType>::iterator actionIt;
In the class destructor, actions.clear() is called. This call inside the
destructor at runtime led to an access violation inside _Orphan_ptr of
std::xtree via the std::map data member. However, calling the
actions.clear()
elsewhere didn't have such access violation problem. This led me to wonder
what destruction order between member methods and destructor of a class
instance.
There is really no such thing as destroying methods. They continue to exist
in memory even after an object is destroyed. (And, they exist even before an
object is created.) But they can't be called without an object pointer, so
perhaps that is the source of your problem.
--
Scott McPhillips [VC++ MVP]
Doug Harrison [MVP]
2010-04-30 02:27:28 UTC
Permalink
Post by Chris
Hi there,
A class usually has non-static member method(s). When an instance of such
class gets destroyed, is its non-static member method destroyed before its
destructor is called? The reason I raised this question is that I faced the
I have a class which has a member data of std::map type. The map member data
has entries that are pointers to the member methods of the class, like
typedef void (MyClass::*ActionMethodType)(const char*);
std::map<string, ActionMethodType> actions;
typedef std::map<string, ActionMethodType>::iterator actionIt;
In the class destructor, actions.clear() is called. This call inside the
destructor at runtime led to an access violation inside _Orphan_ptr of
std::xtree via the std::map data member. However, calling the actions.clear()
elsewhere didn't have such access violation problem. This led me to wonder
what destruction order between member methods and destructor of a class
instance.
Functions aren't created or destroyed; they always exist (DLLs
notwithstanding). As for non-static member data, it is still valid inside
the destructor of the object whose class defines the variables. After you
exit the destructor, non-static member data and base class subobjects are
destroyed in the reverse order of their initialization. You certainly
should be able to call actions.clear() inside the destructor, though it
isn't necessary, because the map will be destroyed as previously described
if you do nothing. You should be able to call clear() over and over again
without any harmful effects.

Most likely, either you are corrupting the map somewhere, you have a
one-definition rule (ODR) violation, or you're using DLLs and not linking
everyone to the same CRT DLL, which causes the modules to use different
heaps, such that one module can't delete an object created by another. An
ODR violation could cause a problem similar to the DLL issue within
separately linked parts of a single module. You could also get into trouble
if a base class destructor somehow tried to access the member data of a
derived class, perhaps through a stored pointer to the object, which is
always wrong.
--
Doug Harrison
Visual C++ MVP
Loading...