From: Chris on
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

From: Scott McPhillips [MVP] on
"Chris" <Chris(a)discussions.microsoft.com> wrote in message
news:13BFF7B6-67D3-4D66-99C4-9DDC481AF8ED(a)microsoft.com...
> 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.


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]

From: Doug Harrison [MVP] on
On Thu, 29 Apr 2010 18:59:01 -0700, Chris <Chris(a)discussions.microsoft.com>
wrote:

>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.

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