哪位大牛帮忙看看我的com是单线程,且一直存活,vc++2005
在com中通过全局allmap保存数据//map部分应该没问题
allmap的value是自定义类CTest,类中有三个成员:char m_c1[20],char m_c2[20],char m_c3[20]
com接口是 getstate([out] variant* OutState,[out,retval] variant* OutRet)
{
         CTest c=allmap[key];
         OutState->vt=VT_BSTR;
OutState->bstrVal=_bstr_t(c.m_c1).copy();//怀疑这句这么写有内存泄露,
OutRet->vt=VT_BOOL;
OutRet->boolVal=bRet;
}

解决方案 »

  1.   

    回二楼,我其实有一个单独的接口会将map.clear()的
    在vbs中我
    for i =1 to 50000
        set obj=createobject("xxxx")
        bret=obj.getstate(a)
        bret=obj.mapclear()
        a=""
        set obj=nothing
    next 
    com中OutState->bstrVal=_bstr_t(c.m_c1).copy();
    有没有注释,从任务管理器中看,使用的内存差距比较大。
      

  2.   

    copy会出现内存泄露, 需要用上述函数释放 , 具体可以看msdn
      

  3.   

    OutState->bstrVal=_bstr_t(c.m_c1).copy();//怀疑这句这么写有内存泄露,
    这一句的确泄露了,楼主看下Copy 的代码应该知道为什么泄露了吧 
    inline BSTR _bstr_t::Data_t::Copy() const throw(_com_error)
    {
    if (m_wstr != NULL) {
    BSTR bstr = ::SysAllocStringByteLen(reinterpret_cast<char*>(m_wstr),
    ::SysStringByteLen(m_wstr)); if (bstr == NULL) {
    _com_issue_error(E_OUTOFMEMORY);
    } return bstr;
    } return NULL;
    }
      

  4.   

    _bstr_t和variant_t一直没搞懂,学习
      

  5.   

    请问六楼,vbs中如何释放com中bstr占用的内存
      

  6.   

    utState->bstrVal=_bstr_t(c.m_c1).copy();  //这里不用再copy
      

  7.   

    值得商榷
    另外你可以把bstrVal 声明为_bstr_t,不要声明为BSTR
    返回的BSTR副本,是由调用copy的那一方负责维护析构的。
    而且BSTR本身不具备_bstr_t管理释放的能力按照你原来的代码
    就看你是如何声明bstrVal,如何负责释放bstrVal.
    最好多贴些代码。你的代码倒不是一定引起内存泄露,可能是你没有管理好这个BSTR,或者直接声明为BSTR了
      

  8.   

    vbs中Set =nothing 可以不?
      

  9.   

    根据以往的经验,声明变量时类型不用用BSTR,可以用_bstr_t或CComBSTR,这些封装类自己会处理内层的释放,不用再手动调用 ::SysFreeString 了,很easy的。
      

  10.   

    你的代码里没有泄漏。 不过在调用方需要用SysFreeString去清除,如果调用方不手动清除那么肯定就会泄漏
      

  11.   


    ::sysfreestring();//正解
    //目前如下解决:
    //在对某VARIANT*(使用bstrVal)赋值前要先清空
    if(OutState->bstrVal != NULL0
    {
        ::SysFreeString(OutState->bstrVal);
        OutState->bstrVal=NULL;
    }
    //CComBSTR 我试过了好像不能解决问题呀,是不是方法有误呢,哪位老大给个简单例子
    //OutState->bstrVal=CComBSTR("需要返回的字符串").copy();
    //和_bstr_t("需要返回的字符串").copy();效果一样啊
      

  12.   

    上面写错了::sysfreestring();//正解
    //目前如下解决:
    //在对某VARIANT*(使用bstrVal)赋值前要先清空
    if(OutState->bstrVal != NULL)
    {
        ::SysFreeString(OutState->bstrVal);
        OutState->bstrVal=NULL;
    }
    //CComBSTR 我试过了好像不能解决问题呀,是不是方法有误呢,哪位老大给个简单例子
    //OutState->bstrVal=CComBSTR("需要返回的字符串").copy();
    //和_bstr_t("需要返回的字符串").copy();效果一样啊
      

  13.   

    ::VariantClear(OutState);
    OutState->vt = VT_BSTR | VT_BYREF;
    *OutState->pbstrVal = _bstr_t(c.m_c1).copy();
      

  14.   

    写错了,上面的代码会出错,不应该调用VariantClear。if (OutState->vt == VT_BSTR | VT_BYREF)
    {
      if (*OutState->pbstrVal) ::SysFreeString(*OutState->pbstrVal);
      *OutState->pbstrVal = _bstr_t(c.m_c1).copy();
    }