__ bstr_t内存泄漏

问题描述 投票:4回答:4

我有一个c ++代码。但是它不能正确释放内存。告诉我我错了,这里是我的代码

1 void MyClass::MyFunction(void)
2 {
3    for (int i=0; i<count; i++)
4    {
5        _bstr_t xml = GetXML(i);
6        // some work
7        SysFreeString(xml);
8    }
9 }

GetXML(第5行)返回了一个BSTR。在此程序存储增加。但是在SysFreeString(第7行)之后,内存不会释放。我在这里做错了吗?

c++ memory-management memory-leaks bstr
4个回答
8
投票

第一:

// This makes a copy.
// This is where the leak is. You are leaking the original string.
_bstr_t xml = GetXML();

// You want to use this, to attach the BSTR to the _bstr_t
_bstr_t xml = _bstr_t(GetXML(), false);

第二,不要这样做

SysFreeString(xml); 

_bstr_t类将为您做到这一点。

[第三,BSTR不会立即将内存释放给操作系统,它会缓存最近使用的字符串,以使SysAllocString更快。您不应该期望在SysFreeString之后看到内存使用率急剧下降。

您可以控制此行为以进行调试:

最后,在任务管理器中查看内存使用情况时,您需要查看“提交大小”列而不是“工作集”。转到菜单->查看->选择列以显示该列。还请注意,这确实只能在一段时间内提供帮助-内存可能不会立即释放到操作系统,但是如果您没有泄漏,则它不会在数小时内永久耗尽。


1
投票

我想您应该使用:

xml.Attach(GetXML(i));

operator =看起来实际上是在分配新值-这意味着要复制它。 GetXML返回的值保持未释放状态。

也应该不需要SysFreeString(xml);


0
投票

任务管理器仅提供分配给该进程的内存量。当C ++释放内存(C的免费版本)时,它不一定将内存返回给操作系统,因此,任务管理器在进程结束之前不一定会显示内存即将运行。

任务管理器可以显示的是,如果您继续分配内存而不释放它,则该进程的内存大小将不断增加,如果发生这种情况,您可能会发生内存泄漏。

编程时,您需要使用内存探查器来查看是否释放内存。在Windows中,我使用Rational的Purify为我提供了此信息,但是它花费很多。 MS C运行时可用于跟踪内存。 MSDN在此处提供概述,请阅读并关注链接。

关于您的代码以及其他注释和答案,使用_bstr_t类的要点之一是为您执行内存和其他资源管理,因此您不应调用SysFreeString。>


0
投票

_bstr_t的析构函数将调用SysFreeString(xml),因此您无需再次调用SysFreeString(xml)。额外的可用内存将导致崩溃。


推荐问答