作为通用指针类型传递的 SmartPointers 是不是需要在传递给另一个函数之前被释放?

Posted

技术标签:

【中文标题】作为通用指针类型传递的 SmartPointers 是不是需要在传递给另一个函数之前被释放?【英文标题】:Do SmartPointers passed as a generic pointer type need to be freed before passing to another function?作为通用指针类型传递的 SmartPointers 是否需要在传递给另一个函数之前被释放? 【发布时间】:2020-12-30 11:57:47 【问题描述】:

我认为智能指针在作为被赋值的通用指针类型传递时需要特别删除,否则会发生内存或资源泄漏?

我将以CComPtr 为例。会不会泄露:

CComPtr<ISomeComObj> mycomobj;
SomeOtherComObject1->FunctionToFindComObject(&mycomobj);
SomeOtherComObject2->FunctionToFindComObject(&mycomobj);

如果是这样,我认为解决方案是:

CComPtr<ISomeComObj> mycomobj;
SomeOtherComObject1->FunctionToFindComObject(&mycomobj);
mycomobj=NULL;
SomeOtherComObject2->FunctionToFindComObject(&mycomobj);

或 CString 示例:

void GetString(char **pstring)

  *pstring=new char[123];
  strncpy(*pstring, "Whatever", 122);


// this leaks, correct?
CString s;
GetString(&s);
GetString(&s);
    
// this is okay, correct?
CString c;
GetString(&c);
c=NULL;
GetString(&c);

?

【问题讨论】:

【参考方案1】:

这最终取决于开始指针和函数的编写方式,但总的来说,ATL 指针和函数应按应有的方式编码:

在调试模式下:

CComPtr<ISomeComObj> mycomobj;
SomeOtherComObject1->FunctionToFindComObject(&mycomobj);
SomeOtherComObject2->FunctionToFindComObject(&mycomobj); // will throw an ATL assert

atlcomcli.h中提取:

...
//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;

...

在发布时,您会遇到问题。所以你应该做的是:

CComPtr<ISomeComObj> mycomobj;
SomeOtherComObject1->FunctionToFindComObject(&mycomobj);
mycomobj.Release();
SomeOtherComObject2->FunctionToFindComObject(&mycomobj);

请注意,即使包含的指针为空,CComPtr::Release() 也可以安全地调用(在调试和发布模式下),所以这很好,例如:

CComPtr<ISomeComObj> mycomobj;
mycomobj.Release();

PS:我的建议是始终使用调试模式进行开发。

【讨论】:

以上是关于作为通用指针类型传递的 SmartPointers 是不是需要在传递给另一个函数之前被释放?的主要内容,如果未能解决你的问题,请参考以下文章

将模板化智能指针类型作为模板参数传递

将实例化的 System.Type 作为通用方法的类型参数传递

无论传递了迭代器类型/指针,指向元素的地址

通过 QT 的信号/槽系统作为参数传递通用异常

使用指针数组作为函数的参数

Golang学习 - unsafe 包