• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >vc/mfc > 请教,关于多线程激发事件时,造成的内存泄漏问题,100分诚赠。

请教,关于多线程激发事件时,造成的内存泄漏问题,100分诚赠。

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-04

佚名通过本文主要向大家介绍了多请教,余生请多请教,余生多请教,请教的意思,请教学霸8 6 13 8等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: 请教,关于多线程激发事件时,造成的内存泄漏问题,100分诚赠。
描述:

*概要
  ATL的封装函数IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt(int nConnectionIndex)在其内部调用IGlobalInterfaceTable::GetInterfaceFromGlobal(DWORD dwCookie, REFIID riid,void **ppv)时发生内存泄漏,原ATL封装函数如下:
template <class T, const IID* piid, class CDV>
LPUNKNOWN IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt(
int nConnectionIndex)
{
m_CPMTCritSec.Lock();
LPUNKNOWN pUnk = NULL;
// IConnectionPointImplMT Vector stores DWORDs instead of IUnknown pointers, 
// explicit cast required:
DWORD dwGITCookie = (DWORD)(m_vec.GetAt(nConnectionIndex));
if (dwGITCookie != NULL)
{
IID iid;
GetConnectionInterface(&iid);
//HRESULT hr = S_OK;
/*!*/ HRESULT hr = m_pGIT->GetInterfaceFromGlobal(  // <- 就是这条!!
dwGITCookie, iid, reinterpret_cast<void **>(&pUnk));
ATLASSERT(hr == S_OK);
}
m_CPMTCritSec.Unlock(); 
return pUnk;
}
*我实在找不到解决方法
  我想当然:既然GetInterfaceFromGlobal()申请了资源,必然有一个对应的函数可以释放掉,但我仔细阅读过MSDN,也都仔细试过,三个函数没有一个能实现:IGlobalInterfaceTable::GetInterfaceFromGlobal()
IGlobalInterfaceTable::RegisterInterfaceInGlobal()
IGlobalInterfaceTable::RevokeInterfaceFromGlobal()
*我也全都按照微软网站上的方法做了
把
class CProxy_IEvntFirerEvents : public IConnectionPointImpl<T, &DIID__IEvntFirerEvents, CComDynamicUnkArray>
换成
class CProxy_IEvntFirerEvents : public IConnectionPointImplMT<T, &DIID__IEvntFirerEvents, CComDynamicUnkArray>
把
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
换成
CComPtr<IUnknown> sp;
sp.Attach (GetInterfaceAt(nConnectionIndex));
我也试了其它的释放方法,要么行不通,要么无效。
请各位高手帮我,谢谢!


解决方案1:

作为多进程的GlobalTable如果不对每个线程调用::CoUnInitialize(),就会导致列集信息无法释放,建议不要实用::CoInitializeEx(NULL,COINIT_MULTITHREADED)

解决方案2:

m_pGIT->Release()应该和m_pGIT->GetInterfaceFromGlobal匹配,你在什么地方Release的?次数是否一样?

解决方案3:

我估计这个问题是线程调度问题。
不知道你用的是什么管理方式Free,Both?
你可以试一试自己调度
CoMarshalInterThreadInterfaceInStream
CoGetInterfaceAndReleaseStream

解决方案4:

那段代码是VC向导产生的,没有问题,不必费心去修改他。关键是这个函数不能从COM对象创建线程外引用。即不能在工作线程中调用这个函数,否则会引起客户端崩溃。MS中有关于COM对象内部多线程引发客户端事件的方法,记不清位置了。如有需要可以联系。

解决方案5:

m_pGIT->GetInterfaceFromGlobal(dwGITCookie, iid, reinterpret_cast<void **>&pUnk))没有引起内存泄漏。
你是不是用了这样
[CComQIPtr<T>] = [IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt(int nConnectionIndex)]
这样的方式赋值?这才是内存泄漏的根源。从函数的实现来说,GetInterfaceAt(int nConnectionIndex)返回的指针就应该存在一个引用,因为调用者必须保证这个对象在函数外围的一切调用都在它的生存周期内,所以最终得由调用者释放这个指针。
但是这里,只能指针CComQIPtr<>或者类似的智能指针再给它加了一个引用,这才是问题的根本所在。你改用CComPtr<IYouinterface> sp; sp.p = ...GetInterfaceAt()就可以解决这个问题。
另外,这样的函数不是很好的设计,一般用作自己内部用,如果作为公共模块暴露给其它调用者,一般不会这样,除了上面说的原因外,还要防止可以调用这个函数而没有使用返回值,这样跟上面的理由一般,也是一个内存泄漏。因此,如果作为公共模块的接口,一般会用参数IYouinterface** pp代替。API,CRT函数也是类似的,例如,除了HeapAlloc(),GlobalAlloc(),LocalAlloc(),malloc(), operator new()等少数几个分配内存的函数外,一般都不会在函数体内把一部分内存所有权放弃,然后作为返回值交给客户。
CString::operator LPCTSTR()等函数虽然也返回指针,但是,它对字符串的内存并不会把所有权交给它的调用者,而是始终由CString类保持着引用,并总是由CString释放。也跟上面类似的道理。

解决方案6:

ATL里哪里来的IConnectionPointImplMT?我怎么从来没看到过?是你自己定义的吧?
不过你的问题很简单,主要是这个函数定义的有问题:
LPUNKNOWN IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt( int nConnectionIndex);
只要你直接调用GetInterfaceAt(nConnectionIndex);这样就内存泄露了,因为返回的临时对象不会被自动析构。
除非像这样写,手工删除返回的对象:
LPUNKNOWN p = GetInterfaceAt(nConnectionIndex);
p->Release();
所以返回COM对象一定要用智能指针,否则很容易造成内存泄露。


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 请教一个多线程的问题
  • 请教多线程的自动启动?
  • 请教各位一个多线程中数据共享的问题,立即加分,先谢了
  • 高分请教多线程调用问题
  • 请教一个多线程的ADO问题。
  • 请教一个关于多线程的问题。
  • 请教多线程问题——谢谢!
  • 请教:多线程下刷新Bitmap的问题
  • 请教一个关于多线程中显示图像的问题
  • 请教:多线程处理问题。

相关文章

  • 2017-06-05 多线程能否共用一个全局函数?当每个线程同时访问这个函数时会不会影响这个全局函数里面的变量或者全局变量?谢谢。
  • 2017-06-04 关于BHO拦截按键的问题
  • 2017-06-04 一个简单的ATL生成组件就是不能被创建
  • 2017-06-05 ActiveX控件属性的问题!
  • 2017-06-05 VS2010环境下用C++做ADO开发,费解的freec错误
  • 2017-06-05 高分求助:知道一个子进程的ID,如何获得该子进程启动的进程,需要进行同步,急
  • 2017-06-04 急添加NewATLObject失败!!望高手解救
  • 2017-06-04 VC++中如何开发使用控件。。
  • 2017-06-04 请教高手shell问题
  • 2017-06-05 wtl中如何添加自定义消息,请高手指点

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 奇怪!VS2005ATL项目不能向接口添加方法?
    • 关于OCX重画的问题
    • 请帮忙,CHtmlView如何设置为“从右到左的文档”?蒋老大救命!
    • 新建个WebBrowser控件,怎么获得IWebBrowser2的接口哦
    • 使用他人的dll出现了以下错误,怎么办?
    • 一个基于ATLCOM的Dialog的ComboBox问题
    • ATL中如何使用进度条?
    • VS2008写ATLCOM编译自动注册了,我不想自动注册
    • 第三次提问COM控件阻塞问题,真的没有人知道么?CSDN真的无人么?
    • 域普通用户如何使用activex?

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有