C++ Webbrowser(COM)内存泄漏

C++ Webbrowser(COM)内存泄漏,c++,com,memory-leaks,browser,C++,Com,Memory Leaks,Browser,这段代码会产生巨大的内存泄漏。你能帮我找出它发生在哪里吗 此代码执行以下操作: 1) 它获取IHTMLDocuments2接口 2) 对所有标签集合的请求 3) 迭代整个集合 4) 并将一些标记的数据添加到列表中 IDispatch* pDisp; pDisp = this->GetHtmlDocument(); if (pDisp != NULL ) { IHTMLDocument2* pHTMLDocument2; HRESULT hr; hr = pDis

这段代码会产生巨大的内存泄漏。你能帮我找出它发生在哪里吗

此代码执行以下操作:

1) 它获取IHTMLDocuments2接口 2) 对所有标签集合的请求 3) 迭代整个集合 4) 并将一些标记的数据添加到列表中

IDispatch* pDisp;
pDisp = this->GetHtmlDocument();

if (pDisp != NULL ) 
{
    IHTMLDocument2* pHTMLDocument2;
    HRESULT hr;
    hr = pDisp->QueryInterface( IID_IHTMLDocument2,(void**)&pHTMLDocument2 );
    if (hr == S_OK)
    {
                    // I know that I could use IHTMLDocument3 interface to get collection by ID
                    // but it didn't worked and returned NULL on each call.
        IHTMLElementCollection* pColl = NULL;
                    // get all tags
        hr = pHTMLDocument2->get_all( &pColl );
        if (hr == S_OK && pColl != NULL)
        {
            LONG celem;
            hr = pColl->get_length( &celem );
            if ( hr == S_OK )
            {
                                    //iterate through all tags
                                    // if I iterate this block of code in cycle, it 
                                    // uses memory available upto 2GBs and then
                                    // app crashes
                for ( int i=0; i< celem; i++ )
                {                       
                    VARIANT varIndex;
                    varIndex.vt = VT_UINT;
                    varIndex.lVal = i;
                    VARIANT var2;
                    VariantInit( &var2 );
                    IDispatch* pElemDisp = NULL;
                    hr = pColl->item( varIndex, var2, &pElemDisp );
                    if ( hr == S_OK && pElemDisp != NULL)
                    {
                        IHTMLElement* pElem;
                        hr = pElemDisp->QueryInterface(IID_IHTMLElement,(void **)&pElem);
                        if ( hr == S_OK)
                        {                   
                                                            // check INPUT tags only
                            BSTR tagNameStr = L"";
                            pElem->get_tagName(&tagNameStr);
                            CString tagname(tagNameStr);
                            SysFreeString(tagNameStr);
                            tagname.MakeLower();
                            if (tagname != "input")
                            {
                                continue;
                            }
                                                            //get ID attribute
                            BSTR bstr = L"";
                            pElem->get_id(&bstr);
                            CString idStr(bstr);
                            SysFreeString(bstr);

                            if (RequiredTag(pElem)) 
                            {       
                                AddTagToList(pElem);
                            }
                                                            //release all objects
                            pElem->Release();
                        }
                        pElemDisp->Release();
                    }
                }
            }
                            // I looked over this code snippet many times and couldn't find what I'm missing here...
            pColl->Release();
        }
        pHTMLDocument2->Release();
    }
    pDisp->Release();       
}
IDispatch*pDisp;
pDisp=this->GetHtmlDocument();
如果(pDisp!=NULL)
{
IHTMLDocument2*pHTMLDocument2;
HRESULT-hr;
hr=pDisp->QueryInterface(IID_IHTMLDocument2,(void**)和pHTMLDocument2);
如果(hr==S_正常)
{
//我知道我可以使用IHTMLDocument3接口按ID获取集合
//但它不起作用,每次调用都返回NULL。
IHTMLElementCollection*pColl=NULL;
//获取所有标签
hr=pHTMLDocument2->get_all(&pColl);
如果(hr==S_OK&&pColl!=NULL)
{
长柱;
hr=pColl->get_length(&celem);
如果(hr==S_正常)
{
//遍历所有标记
//如果我在循环中迭代这段代码,它
//使用高达2GB的可用内存,然后
//应用程序崩溃
for(int i=0;iitem(varIndex、var2和pElemDisp);
如果(hr==S_OK&&pElemDisp!=NULL)
{
IHTMLElement*pElem;
hr=pElemDisp->QueryInterface(IID_ihtmlement,(void**)和pElem);
如果(hr==S_正常)
{                   
//仅检查输入标记
BSTR标记名称TR=L“”;
pElem->get_标记名(&tagNameStr);
CString标记名(tagNameStr);
SysFreeString(tagNameStr);
标记名.MakeLower();
如果(标记名!=“输入”)
{
继续;
}
//获取ID属性
BSTR BSTR=L”“;
pElem->get_id(&bstr);
CSTR(bstr);
SysFreeString(bstr);
如果(要求标签(pElem))
{       
附加列表(pElem);
}
//释放所有对象
pElem->Release();
}
pElemDisp->Release();
}
}
}
//我看了很多遍这个代码片段,都找不到我缺少的东西。。。
pColl->Release();
}
pHTMLDocument2->Release();
}
pDisp->Release();
}

在循环中,对于每个检索的元素,如果它没有标记名
“input”
(这将是大多数元素),调用
continue
时,您没有调用
pElem->Release()
,因此您正在泄漏它们:

if (tagname != "input") 
{ 
    pElem->Release(); // <-- add this
    continue; 
} 

在循环中,对于没有标记名为“input”(这将是大多数元素)的每个检索元素,在调用
continue
时,您没有调用
pElem->Release()
,因此您正在泄漏它们:

if (tagname != "input") 
{ 
    pElem->Release(); // <-- add this
    continue; 
} 

好。。。
AddTagToList()
做什么?嗯。。。
AddTagToList()
做什么?