views:

924

answers:

1

Hi,

I have following block of code

 /////////////////////////////////////
 CComVariant newVal;

 //pass the CComVariant and get the strings array!!!
 GetStrList(newVal);
 USES_CONVERSION;

 if (((newVal.vt & VT_ARRAY) == VT_ARRAY) && ((newVal.vt & VT_BSTR) == VT_BSTR))
 {
SAFEARRAY* paArray = newVal.parray;
BSTR * str = NULL;
SafeArrayAccessData(paArray, (void**)&str);

SafeArrayUnaccessData(paArray);

long lLBound = 0;
long lUBound = 0;
long nCount = 0;

if (FAILED(SafeArrayGetLBound(paArray, 1, &lLBound)) ||
 FAILED(SafeArrayGetUBound(paArray, 1, &lUBound)))
{
 ASSERT(false);
 return FALSE;
}


nCount = ( lUBound - lLBound + 1 );
for (int i = 0 ; i < nCount ; i++)
{   
 m_cstrList.AddString(W2T(str[i]));     
} 
//SafeArrayDestroy(paArray); ---> is it required here???

 }

 /////////////////////////////////////

method returing the safe arrays

 HRESULT GetStrList(VARIANT *pVal)
 {
USES_CONVERSION;

if (!pVal)
 return E_FAIL;

SAFEARRAYBOUND bound[1]; //single dimension array
bound[0].lLbound = 0;
bound[0].cElements = 10;

SAFEARRAY * A = SafeArrayCreate(VT_BSTR, 1, bound);

BSTR * str = NULL;
SafeArrayAccessData(A, (void**)&str);

//user wants the NT view OPC drivers list.
for (int i=0;i<10;i++)
{  
 str[i] = SysAllocString(T2W(mystrings[i]));  
}


VariantInit(pVal);
pVal->vt  = VT_ARRAY | VT_BSTR;
pVal->parray = A;

SafeArrayUnaccessData(A);
A = NULL;

return S_OK;
 }

My doubt is, above first block of code has any memory leaks? Does the CComVariant itself handle every thing about the cleaning? or do i also manually do SafeArrayDestroy(paArray);

Thanks in Advance!

+2  A: 

CComVariant destructor calls VariantClear() which frees whatever the variant was incapsulating, arrays included.

One caveat: the array should not be locked at the time when VariantClear() is called. This means that if an exception is thrown after SafeArrayAccessData() but before SafeArrayUnaccessData() the latter will not be called and VariantClear() will not free resources.

Therefore you better write a bracket class for pairing SafeArrayAccessData() and SafeArrayUnaccessData() calls.

sharptooth
if i am doing SafeArrayDestroy(paArray);then i am not getting crashes. According to you, CComVariant should also again destroy the same array, trying to destroy the array which is already destroyed.
coolcake
Well, yes. Maybe it doesn't crash just by accident, but MSDN says that VariantClear() frees not-locked arrays. So trying to free them manually would lead to double-freeing which is not good at all.
sharptooth
So should i not use SafeArrayDestroy for CComVariant?
coolcake
Nope, you should not. Any array which is not locked at that moment will be freed like if you've called SafeArrayDestroy() manually. Just be sure that at the time CComVariant's destructor is invoked the array is not locked.
sharptooth
thank you very much!!!
coolcake