开发者

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

  1. You don't always know if that server is written in C++. Doing delete on a non-C++ object is undefined behavior.
  2. 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.
  3. You call delete on an interface pointer that is declared as not having a virtual destructor - that's undefined behavior.
  4. You don' always know if you've been served a real object or a proxy. Doing delete on a proxy is undefined behavior.
  5. Once you called Release() the object may have already self-deleted and doing delete again is undefined behavior.
  6. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜