Memory leak - release and delete
IFSUPCUTILSize* size = NULL;
CoCreateInstance(CLSID_UTILSize, NULL, CLSCTX_INPROC_SERVER, IID_IFSUPCUTILSize, reinterpret_cast<void**>(&size));
if (size != NULL){
size->Release();
size = NULL;
}
delete size;
Do I need "delete size" in the code above?
If I include "delete size", will I have a memory leak be开发者_运维知识库cause I did not use New?
Or is there a New inside the call to CoCreateInstance
.
I built this with VC++ 6.
COM interfaces are reference counted. CoCreateInstance()
returns an interface pointer to a COM object whose reference count has already been incremented. Calling Release()
decrements the reference count. When the reference count falls to zero, the COM object frees itself automatically. DO NOT call delete
on a COM interface pointer! Always use Release()
only.
From a C++ perspective, what you're doing is fine. Calling delete on a null pointer is a no-op. However, it's unnecessary.
From a VC++6 perspective, I cannot say, it's notoriously non-compliant. I can't imagine why it might be a problem though. But again, it's certainly unnecessary.
Definitely do not call delete on this pointer before it's set to NULL. You did not allocate with new, so don't call delete. Resource management here is taken care of by the COM functions.
Never try to use delete
to release COM servers implemented by another module (that's your case).
- You don't always know if that server is written in C++. Doing
delete
on a non-C++ object is undefined behavior. - Even if the server is written in C++, you don't know on which heap it was allocated and whether
delete
will deallocate memory properly or trigger undefined behavior. - You call
delete
on an interface pointer that is declared as not having a virtual destructor - that's undefined behavior. - You don' always know if you've been served a real object or a proxy. Doing
delete
on a proxy is undefined behavior. - Once you called
Release()
the object may have already self-deleted and doingdelete
again is undefined behavior. - Some third party might have taken ownership of the object -for example, some global pointer instance might have been set to your object. If you
delete
those other pointers will become dangling and that will likely cause undefined behavior later.
Bottom line: don't use delete
in this case ever. Call Release()
to release ownership of the object and that will be enough.
If I include "delete size", will I have a memory leak because I did not use New.
You generally won't get a memory leak by calling delete
. You can and many times will get memory corruption. The two are very different: a memory leak means that your program holds onto memory that it doesn't actually use, over time the program might crash if the leaked memory continues to grow; memory corruption means that you somehow clobbered important bookkeeping structures in memory, and likely will crash very soon (at least you ought to hope for a crash, the alternative is worse). One very common cause of memory corruption is deallocating memory with the wrong routine, especially on Windows (it's something of a tradition to redefine malloc
and free
on UNIX, so UNIX systems often go out of their way to make sure it's possible to do that).
Or is there a New inside the call to CoCreateInstance
Whatever's inside CoCreateInstance
should be handled by Release()
. At the very least, you should never deallocate memory just because you have a pointer. You need to know how they memory was allocated in order to deallocate it correctly.
I am assuming that size->Release() is releasing OS resources (file handles etc). Therefor put the delete size immediately after before setting size to null.
精彩评论