Proper cleanup of CComSafeArray<VARIANT>

1.7k views Asked by At

Given:

{
    CComSafeArray<VARIANT> sa;
    CComVariant ccv(L"test");
    sa.Add(ccv, TRUE);
}

I was hoping the dtor of CComSafeArray would call ::VariantClear on each contained member and the documentation seems to indicate that:

In certain cases, it may be preferable to clear a variant in code without calling VariantClear. For example, you can change the type of a VT_I4 variant to another type without calling this function. Safearrays of BSTR will have SysFreeString called on each element not VariantClear. However, you must call VariantClear if a VT_type is received but cannot be handled. Safearrays of variant will also have VariantClear called on each member.

(source: http://msdn.microsoft.com/en-us/library/windows/desktop/ms221165(v=vs.85).aspx)

But I see no such thing happening in the code in atlsafe.h.

Am I just looking in the wrong place or is this just supposed to happen as a side-effect of ::SafeArrayDestroy() -- which is the only thing happening via the CComSafeArray dtor.

1

There are 1 answers

0
dlanod On BEST ANSWER

Ultimately VariantClear will get called on the contents of the CComSafeArray object, albeit after progressing through multiple layers. CComSafeArray::~CComSafeArray() calls CComSafeArray::Destroy() which is ultimately a wrapper of SafeArrayDestroy():

HRESULT Destroy()
{
    HRESULT hRes = S_OK;
    if (m_psa != NULL)
    {
        hRes = Unlock();
        if (SUCCEEDED(hRes))
        {
            hRes = SafeArrayDestroy(m_psa);
            if (SUCCEEDED(hRes))
                m_psa = NULL;
        }
    }
    return hRes;
}

SafeArrayDestroy() is documented as calling VariantClear on its contents if it contains VARIANTs:

Safe arrays of variant will have the VariantClear function called on each member and safe arrays of BSTR will have the SysFreeString function called on each element.