2

次のコードブロックがあります

 /////////////////////////////////////
 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???

 }

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

セーフ配列を返すメソッド

 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;
 }

私の疑いは、コードの最初のブロックの上にメモリリークがありますか? CComVariantそれ自体がクリーニングに関するすべてのことを処理しますか? または私も手動で行いますかSafeArrayDestroy(paArray);

前もって感謝します!

4

1 に答える 1

3

CComVariant デストラクタは VariantClear() を呼び出します。これにより、バリアントがカプセル化していたもの、配列が含まれているものはすべて解放されます。

1 つの注意点: VariantClear() が呼び出された時点で配列をロックしないでください。つまり、SafeArrayAccessData() の後、SafeArrayUnaccessData() の前に例外がスローされた場合、後者は呼び出されず、VariantClear() はリソースを解放しません。

したがって、SafeArrayAccessData() と SafeArrayUnaccessData() 呼び出しをペアにするためのブラケット クラスを作成することをお勧めします。

于 2009-03-12T09:04:54.167 に答える