Mistake #1: Not Freeing Memory Allocated by SafeArrayGetElement() When Using VariantsWhen you use SafeArrayGetElement(), be sure to free the memory that has been allocated for the copy of the safe array element.
It is the caller's job to allocate memory for this function to copy the safearray data element into, and therefore it is also the caller's job to release this memory when finished with it. SafeArrayGetElement() will allocate the memory for the data in the Variant (such as for a BSTR), and it is the caller's job to free all memory that is associated with the variant. The best approach for doing this is to use the VariantClear() function. Here is an example:
VARIANT varMyVal; // Variant allocated on stack
ix = 1;
// If the element in the safe array fetched was a BSTR, then the
// appropriate memory will be allocated for it, on the heap
hResult = SafeArrayGetElement(m_psa, &ix, &varMyVal);
// This will free the memory for the data element retrieved from
// the Safe Array (say a BSTR)
Mistake #2: Not Calling Release on COM Interface Pointers When Using QueryInterface()When you are using in-process COM components, make sure that you release all interface pointers. If you do not do this, you may leave instances of unused COM components allocated in the process's memory space.
The following code shows the proper handling of a pointer, pObj, obtained via QueryInterface() on an existing object pointed to by pUnk. The pObj->Release(); will decrement the reference count on the object, but the object won't be released from memory at that point because pUnk is still holding a reference to it. When pUnk->Release(); is called, the ref count will go to 0 and the object will be released. If you omit the pObj->Release(); then the pUnk->Release(); will not free the object and you will have a memory leak in your process.
if (!SUCCEEDED(pUnk->QueryInterface(CLSID_MyAtlObj, (void **)&pObj)))
pObj->Release(); // Needed because we called QueryInterface.
Artikelnummer: 264295 – Letzte Überarbeitung: 19.06.2014 – Revision: 1