Unmanaged pointer cleanup in Managed class

M

Maxwell

Hello,

Newbie question here for disposing of unmanaged resources in MC++.NET.
I have a managed VS.NET 2003 MC++ wrapper class that wraps a unmanaged
C++ dll. What I am trying to figure out is what is the "best practice"
for disposing of pointers to unmanaged classes that you have newed in
your constructor in MC++

For a better description of what is the standard affair I have tried
looking online at:
http://msdn.microsoft.com/library/d...ml/vcmg_techniquesconstructorsdestructors.asp

but I would have to say its very lacking in detail or explanation. Does
anyone know of a better reference or can point me to for this?

My constructor looks something like this:

MClass::MClass()
{
pUnmanagedClass_ = new UnmanagedLib::UClass(); //unmanaged heap
pBridgeClass_ = new _UClassBridge(); //unmanaged heap


pUnmanagedClass_->RegisterUnmanagedCallBack(&(pBridgeClass_->UnmanagedBridgeCallback));
}

pUnanagedClass_ is a pointer to class in a unmanaged C++ DLL
pBridgeClass_ is a pointer to a __nogc class I created in MC++

Here is my destructor for this class:
MClass::~MClass()
{
pUnmanagedClass_->UnRegisterCallbacks();
pUnmanagedClass_->~UClass(); ///do I need this line

delete pUnmanagedClass_; //because it was newed
delete pBridgeClass_; //because it was newed
}

Since I newed the pointers I would guess that I would have to
explicitly call delete on them...is this the case? I also need to
ensure that destrutor gets called in the C++ DLL immediately
(pUnmanagedClass) so I added a line for this in the managed class
destructor...is this necessary or is it safe to assume it will get
called because the delete is called

Thanks
 
G

Guest

Maxwell.. I am also new to C++/cli, but I notice that you are doing _two_
unmanaged allocations in the constructor. So if an exception is thrown
_after_ a first successful allocation, the object never exists and the
destructor is never called. So I think the unmanaged allocations in the
constructor need to be all or none, sort of like a transaction. If any part
of the construction fails, then things are rolled back to the "initial state"
and then rethrow the exception.

Hopefully, someone will chime in on this concern.
 
C

Carl Daniel [VC++ MVP]

Maxwell said:
Hello,

Newbie question here for disposing of unmanaged resources in MC++.NET.
I have a managed VS.NET 2003 MC++ wrapper class that wraps a unmanaged
C++ dll. What I am trying to figure out is what is the "best practice"
for disposing of pointers to unmanaged classes that you have newed in
your constructor in MC++

For a better description of what is the standard affair I have tried
looking online at:
http://msdn.microsoft.com/library/d...ml/vcmg_techniquesconstructorsdestructors.asp

but I would have to say its very lacking in detail or explanation.
Does
anyone know of a better reference or can point me to for this?

My constructor looks something like this:

MClass::MClass()
{
pUnmanagedClass_ = new UnmanagedLib::UClass(); //unmanaged heap
pBridgeClass_ = new _UClassBridge(); //unmanaged heap


pUnmanagedClass_->RegisterUnmanagedCallBack(&(pBridgeClass_->UnmanagedBridgeCallback));
}

pUnanagedClass_ is a pointer to class in a unmanaged C++ DLL
pBridgeClass_ is a pointer to a __nogc class I created in MC++

Here is my destructor for this class:
MClass::~MClass()
{
pUnmanagedClass_->UnRegisterCallbacks();
pUnmanagedClass_->~UClass(); ///do I need this line

delete pUnmanagedClass_; //because it was newed
delete pBridgeClass_; //because it was newed
}

Since I newed the pointers I would guess that I would have to
explicitly call delete on them...is this the case? I also need to
ensure that destrutor gets called in the C++ DLL immediately
(pUnmanagedClass) so I added a line for this in the managed class
destructor...is this necessary or is it safe to assume it will get
called because the delete is called

A couple points:

1. You don't need to explicitly call the destructor - the delete expression
will take care of that (in fact, you need to NOT call it, since otherwise
it'll be called twice and classes are not generally expected to handle
having their destructor run twice).

2. If the unmanaged classes are holding important resources (other than just
unmanaged heap), you should consider making your managed class IDisposable
and disposing of the unmanaged class in your IDisposable::Dispose. The
~MClass "destructor" is the finalizer under MC++, and there's no guarantee
that a finalizer will ever run (since there's no guarantee that the GC will
ever run).

3. As another poster pointed out, you're doing multiple allocations in your
constructor with no try/catch protection. You have potential resource leaks
if an exception is thrown in your constructor. If you need to make it
bullet proof, I'd suggest picking up a copy of Herb Sutter's excellent book
"Exceptional C++" - about 1/2 of the book is about building exception
safety.

-cd
 
M

Maxwell

Wow that was great info, That definintely helped tons. Thanks for
pointing out the constructor issue. I was just assuming like in C# if
there was a exception in the constructor the class would not be created
and thus anything that was created in the constructor would be
destroyed automagically...guess not with MC++ because that was
unmanaged code which would make sense.

I'll definintely check out that book,

Thanks again for the replies
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top