CHtmlView 泄漏内存,如果不在几种方法中释放 BSTRs

以下方法在 CHtmlView 会导致内存泄漏如果调用:
  • 导航
  • GetFullName
  • GetType
  • GetLocationName
  • GetLocationURL
  • LoadFromResource(LPCTSTR lpszResource)
  • LoadFromResource(UINT nRes)

原因
此问题是由在"摘要"一节中列出的前五个函数内部的实现中的错误引起的。必须在前五个函数中 分配的 bstr 上调用 SysFreeString。因为在这两种这些函...

此问题是由在"摘要"一节中列出的前五个函数内部的实现中的错误引起的。必须在前五个函数中 分配的 bstr 上调用 SysFreeString。因为在这两种这些函数称为 CHtmlView::NavigateCHtmlView::Navigate 导致泄漏,最后两个函数将导致泄漏。

解决方案
要变通解决此泄漏,"摘要"中列出的函数必须在每个从 CHtmlView 派生的类中实现。如果您有多个视图派生 CHtmlView 一些,请考虑从 CHtmlVi...

要变通解决此泄漏,"摘要"中列出的函数必须在每个从 CHtmlView 派生的类中实现。如果您有多个视图派生 CHtmlView 一些,请考虑从 CHtmlView,使新基类,如 CFixHtmlView,然后派生 CFixHtmlView 代替 CHtmlView 视图中的其余部分:
  1. 在 MFC 应用程序项目中内, 插入一个新的类。在 插入 菜单上单击 新建类别新建类别 对话框中确保 类类型 设置为 MFC 类
  2. 命名类 CFixHtmlView,然后将 基类 组合框项设置为 CHtmlView
  3. FixHtmlView.h 文件中将下面的代码添加到类:
    class CFixHtmlView : public CHtmlView
    {
    //new code
    // Operations
    public:
        CString GetFullName() const;
        CString GetType() const;
        CString GetLocationName() const;
        CString GetLocationURL() const;
    
        void Navigate(LPCTSTR lpszURL, DWORD dwFlags = 0 ,  
                      LPCTSTR lpszTargetFrameName = NULL ,  
                      LPCTSTR lpszHeaders = NULL, LPVOID lpvPostData = NULL,  
                      DWORD dwPostDataLen = 0);
    
    //Add the following functions. This action prevents the leak because the 
    //CHtmlView versions of LoadFromResource() call CHtmlView::Navigate().
    //These need to be defined because CHtmlView::Navigate() is not virtual.
        BOOL LoadFromResource(LPCTSTR lpszResource);
        BOOL LoadFromResource(UINT nRes);
    //end new code
  4. FixHtmlView.cpp 文件中添加以下代码:
    //new code
    CString CFixHtmlView::GetFullName() const
    {
        ASSERT(m_pBrowserApp != NULL);
    
        BSTR bstr;
        m_pBrowserApp->get_FullName(&bstr);
        CString retVal(bstr);
    
        SysFreeString(bstr); // Added this line to prevent leak.
        return retVal;
    }
    
    CString CFixHtmlView::GetType() const
    {
        ASSERT(m_pBrowserApp != NULL);
    
        BSTR bstr;
        m_pBrowserApp->get_Type(&bstr);
    
        CString retVal(bstr);
    
        SysFreeString(bstr); // Added this line to prevent leak.
        return retVal;
    }
    
    CString CFixHtmlView::GetLocationName() const
    {
        ASSERT(m_pBrowserApp != NULL);
    
        BSTR bstr;
        m_pBrowserApp->get_LocationName(&bstr);
        CString retVal(bstr);
    
        SysFreeString(bstr); // Added this line to prevent leak.
        return retVal;
    }
     
    CString CFixHtmlView::GetLocationURL() const
    {
        ASSERT(m_pBrowserApp != NULL);
    
        BSTR bstr;
        m_pBrowserApp->get_LocationURL(&bstr);
        CString retVal(bstr);
    
        SysFreeString(bstr); // Added this line to prevent leak.
        return retVal;
    }
    
    void CFixHtmlView::Navigate(LPCTSTR lpszURL, DWORD dwFlags /* = 0 */,
    	LPCTSTR lpszTargetFrameName /* = NULL */ ,
    	LPCTSTR lpszHeaders /* = NULL */, LPVOID lpvPostData /* = NULL */,
    	DWORD dwPostDataLen /* = 0 */)
    {
        CString strURL(lpszURL);
        BSTR bstrURL = strURL.AllocSysString();
    
        COleSafeArray vPostData;
        if (lpvPostData != NULL)
        {
           if (dwPostDataLen == 0)
              dwPostDataLen = lstrlen((LPCTSTR) lpvPostData);
    
           vPostData.CreateOneDim(VT_UI1, dwPostDataLen, lpvPostData);
        }
    
        m_pBrowserApp->Navigate(bstrURL, COleVariant((long) dwFlags, VT_I4), COleVariant(lpszTargetFrameName, VT_BSTR), 
                                vPostData, COleVariant(lpszHeaders, VT_BSTR));
    
        SysFreeString(bstrURL); // Added this line to prevent leak.
    }
    
    
    BOOL CFixHtmlView::LoadFromResource(LPCTSTR lpszResource)
    {
        HINSTANCE hInstance = AfxGetResourceHandle();
        ASSERT(hInstance != NULL);
    
        CString strResourceURL;
        BOOL bRetVal = TRUE;
        LPTSTR lpszModule = new TCHAR[_MAX_PATH];
    
        if (GetModuleFileName(hInstance, lpszModule, _MAX_PATH))
        {
           strResourceURL.Format(_T("res://%s/%s"), lpszModule, lpszResource);
           Navigate(strResourceURL, 0, 0, 0);
        }
        else
           bRetVal = FALSE;
    
        delete [] lpszModule;
        return bRetVal;
    }
    
    BOOL CFixHtmlView::LoadFromResource(UINT nRes)
    {
        HINSTANCE hInstance = AfxGetResourceHandle();
        ASSERT(hInstance != NULL);
    
        CString strResourceURL;
        BOOL bRetVal = TRUE;
        LPTSTR lpszModule = new TCHAR[_MAX_PATH];
    
        if (GetModuleFileName(hInstance, lpszModule, _MAX_PATH))
        {
           strResourceURL.Format(_T("res://%s/%d"), lpszModule, nRes);
           Navigate(strResourceURL, 0, 0, 0);
        }
        else
           bRetVal = FALSE;
    
        delete [] lpszModule;
        return bRetVal;
    }
    //end new code
  5. 在每个 CHtmlView-派生类的头和源代码文件更改 CHtmlViewCFixHtmlView 到引用的所有代码。若要帮助完成此任务在 编辑 菜单上单击 替换
  6. 确保每个 CHtmlView 中添加下面的代码行的派生类的头文件,在类声明之前:
    #include "FixHtmlView.h" //Add me before the class declaration.
    
    class CMyHtmlView : public CFixHtmlView
    {
    //class body
    };
  7. 重新生成项目。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值