ATL::CComPtr::operator& 断言 Expression: p == 0 原因分析

来源:互联网 发布:火源计划激活码淘宝 编辑:程序博客网 时间:2024/05/17 03:01

一、引言

最近在开发过程中,在使用 ATL::CComPtr 的时候,总会出现一个断言提示:

这里写图片描述

另外,在断言出现处点击“重试”,又可以定位到具体出错的地方:

//The assert on operator& usually indicates a bug.  If this is really  //what is needed, however, take the address of the p member explicitly.   T** operator&() throw()   {    ATLASSERT(p==NULL);    return &p;   }  

这个问题之前遇到过,被老大解决了(T_T 不求甚解的结果就是自己日后还得纠结)。

那么,今天就让我好好的研究下这个问题。

二、stackoverflow: 大神的解释

这个问题翻查了很久,其实上面定位的那段代码里面的解释已经非常清楚了:

The assert on operator& usually indicates a bug. If this is really what is needed, however, take the address of the p member explicitly.

简单翻译下:

在 operator& (取址操作符)经常会指示一个错误。如果它真的是需要的,需要明确的指出 p 的地址。

那么什么叫做“明确的指出 p 的地址”呢?

我们来看看 stackoverflow 上面大神的解释:

The problem is that CComPtr::operator& returns the address of the wrapped pointer but doesn’t release it, therefore leaking the objects if it is declared out of the loop, assuming that the wrapped interface is not NULL.
The implementation acknowledges this fact, this is copied straight from ATL headers, including comments:

//The assert on operator& usually indicates a bug.  If this is really//what is needed, however, take the address of the p member explicitly.T** operator&() throw(){    ATLASSERT(p==NULL);    return &p;}

这是一位大神在解答类似于 ATL::CComPtr::operator& 的问题时的回答,正好使用了 ATL::CComPtr::operator& 的头文件定义给出了回复,这里我尽力简单翻译下:

这个问题的原因是 CComPtr::operator& 返回这个指针的地址却没有释放掉它,如果这个指针对象又恰巧声明在循环之外,并且没有设置值为 NULL,那么就会引起指针对象泄露。
这里的实现又正好佐证了我们的观点,以下是从 ATL 头文件中粘贴的代码,刚好有详细的注释。
(上述的粘贴代码)

可以看到,大神正好作了详细的解释。如果还想详细了解的同学,可以点击这里What is wrong with this Smart Pointer Use?

三、问题解决:p = NULL

那么这个问题就很简单了。

首先,我在调用处,使用了类似下列的代码:

// void thisIsAFunction(Pointer **p);// 希望使用 p 带出我们想要的数据thisIsAFunction(&p);

然而,在传入 thisIsAFunction() 函数中的 &p 参数中的 p 指针并没有明确给出指向对象,所以这里会出文首的提示。

怎么解决呢?

只需要在前面加上这么一行代码:

// void thisIsAFunction(Pointer **p);// 希望使用 p 带出我们想要的数据// p 初始化指向对象为空值p = NULL;thisIsAFunction(&p);

四、总结

关于 ATL::CComPtr 的坑确实不少,理解底层是最好的解决办法。

另外,stackoverflow 是一个很好的社区,就是需要比较高的英语水平:(

原创粉丝点击