简体   繁体   中英

_bstr_t memory leak

I have a c++ code. But it is not releasing memory properly. Tell me where I am wrong, here is my code

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 (line 5) returns me a BSTR. At this memory of program increases. But after SysFreeString (line 7) memory does not release. What I am doing wrong here?

First:

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

Second, don't do this :

SysFreeString(xml); 

The _bstr_t class will do that for you.

Third, BSTR will not release the memory to the OS immediately, it caches recently used strings in order to make SysAllocString faster. You shouldn't expect to see memory usage go straight down after SysFreeString.

You can control this behaviour for debugging purposes:

Lastly, when viewing memory usage in Task Manager you need to look at the column "Commit Size" not "Working Set". Go to Menu->View->Select Columns to show the column. And also note that this really only helps over a period of time - the memory may not be released to the OS immediately, but if you have no leaks, it shouln't go up forever, over a course of hours.

I suppose you should use :

xml.Attach(GetXML(i));

operator= looks like it is actually assigning new value - which means copying it. That value returned by GetXML stays unfreed.

also there should be no need for SysFreeString(xml);

Task Manager only provides the amount of memory allocated to the process. When C++ releases memory ( C's free) it does not necessarily return the memory to the Operating system so Task Manager will not necessarily show memory going doem until the process ends.

What Task Manager can show is if you keep allocating memory and not releasing it then the memory size of the process will keep increasing, if this happens you probably hava a memory leak.

When programming you need to use memory profilers to see if you are releasing memory. In Windows I used Rational's Purify to give me this information but it costs a lot. MS C runtime can be used to track memory. MSDN provides an overview here, read and follow th links.

As to your code and as per other comments and answers one of the points of using _bstr_t class is to do the memory and other resource management for you so you should not call SysFreeString

The destructor of _bstr_t will call SysFreeString(xml), so you don't need to call SysFreeString(xml) again. An additional memory free will result in crash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM