views:

359

answers:

4

Hey Folks,

I have a doubt. I initialize COM, do CoCreateInstance and use some interfaces.Can I call CoUninitialize without calling Release? Does it cause any memory/resource leak?

Thanks in Advance, -Mani.

+3  A: 

From MSDN:

http://msdn.microsoft.com/en-us/library/ms688715%28VS.85%29.aspx

CoUninitialize should be called on application shutdown, as the last call made to the COM library after the application hides its main windows and falls through its main message loop. If there are open conversations remaining, CoUninitialize starts a modal message loop and dispatches any pending messages from the containers or server for this COM application. By dispatching the messages, CoUninitialize ensures that the application does not quit before receiving all of its pending messages. Non-COM messages are discarded.

You should only ever call CoUninitialize on shutdown and by that time it doesn't matter if you have a memory leak.

Igor Zevaka
"You should only ever call CoUninitialize on shutdown". This is notentirely true. You should call it when you destroy any thread that has been CoInitialized. More often than not these threads are killed long before shutdown.
Goz
That's true, I suppose I've never used it in this context.
Igor Zevaka
A: 

AFAIK, CoUninitialize is "supposed" to free all COM resources in use on the current thread. I wouldn't rely on it though. I'd rather make sure I Release everything prior to calling uninitialise.

Goz
A: 

You should not use CoUninitialize() instead of calling IUnknown::Release() for your objects - those are entrirely different functions.

IUnknown::Release() will just decrease a reference count for the object and possibly cause its destruction. In case no marshalling is used this call is done drectly throught the vtable (control is passed directly into the COM server code) and COM subsystem doesn't even do anything for that.

CoUninitialize() will free COM-related resource for the calling thread which I guess are marshalling-related objects. In case no marshalling is used the objects will remain unreleased since only your code knows about them.

That's why you should not use one instead of another.

sharptooth
Thanks. If i indeed use like tat, ie CoUninitialize without calling Release? Does it cause any harms in terms of leakages? I am interesting in this because i need to make changes depending on ur answer
Manigandan
If marshalling is disabled the objects will be leaked. Will you please edit your question and elaborate what, how and why you want to change?
sharptooth
+1  A: 

Regardless of whether you uninitialize COM or not, omitting calls to Release will cause objects to stay alive on the server side, possibly keeping the whole server up for no reason (if not running as a service). In other words, you'll have a memory leak on the server side, which can only be eliminated by restarting the COM server.

I remember asking similar questions when I first started using COM. The client I was working on was using many threads, and I was trying to reuse interfaces for different tasks done by each thread. This made managing the interfaces cache quite difficult. Eventually, there were no shortcuts. Unless you're using MTA, GIT or interface marshaling, the thread that created the interface has to release it as well.

To make it easier on you, try using CComPtr to manage the interfaces you create. As with regular pointers, using smart pointer can sometimes make life much easier for you.

eran
Sorry for the late comment. I solved the problem using CComPtr. Thanks all for your attention.-Mani.
Manigandan