【问题标题】:Problem with SafeArray access using CComVariant使用 CComVariant 访问 SafeArray 的问题
【发布时间】:2010-10-12 20:58:06
【问题描述】:

我有以下代码块

 /////////////////////////////////////
 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);

提前致谢!

【问题讨论】:

    标签: visual-c++ com variant


    【解决方案1】:

    CComVariant 析构函数调用 VariantClear() 来释放任何封装的变体,包括数组。

    一个警告:在调用 VariantClear() 时不应锁定数组。这意味着如果在 SafeArrayAccessData() 之后但在 SafeArrayUnaccessData() 之前引发异常,则不会调用后者并且 VariantClear() 不会释放资源。

    因此,您最好编写一个括号类来配对 SafeArrayAccessData() 和 SafeArrayUnaccessData() 调用。

    【讨论】:

    • 如果我在做 SafeArrayDestroy(paArray);那么我不会崩溃。根据你的说法,CComVariant 也应该再次销毁同一个数组,试图销毁已经被销毁的数组。
    • 嗯,是的。也许它不会偶然崩溃,但 MSDN 说 VariantClear() 释放未锁定的数组。所以尝试手动释放它们会导致双重释放,这根本不好。
    • 那么我不应该对 CComVariant 使用 SafeArrayDestroy 吗?
    • 不,你不应该。如果您手动调用 SafeArrayDestroy() ,那么此时未锁定的任何数组都将被释放。只要确保在调用 CComVariant 的析构函数时,数组没有被锁定。
    猜你喜欢
    • 1970-01-01
    • 2012-05-14
    • 2014-05-15
    • 2017-01-11
    • 1970-01-01
    • 2022-11-11
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多