Tag Archives: VC++

COM, BSTR or _bstr_t is leaking memory

COM, BSTR or _bstr_t is leaking memory. That was my first thought when I saw increasing number in Task Manager under memory colon for the process I am developing.

Searching Google for quick answer I found famous Microsoft employee and blogger Larry Osterman’s blog post about Hey, why am I leaking all my BSTR’s? He describes OLE caching of BSTR objects and tool called UMDH. OLE caching is not my case, however UMDH may be useful is you are able to figure out what to do.

Another link I found is from 1999 (VS6) Implementing a Simple MFC Client for an ATL Server. They have notes about memory leaks all over the place. Particularly interesting are two examples I have copied below.

Without leak:
//Update static text with new value
BSTR tmpBStr;
 
m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr(tmpBStr, FALSE); //necessary to avoid a memory leak
 
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);

With leak:
//Update static text with new value
BSTR tmpBStr;
 
m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr;
 
tmpbstr= tmpBStr; //Caution: Memory leak occurs
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);

And explanation:

The leak occurs when the tmpbstr variable is initialized. A call to SysAllocString (reference available in the Component Services section of the Platform SDK) is automatically made when creating the tmpbstr variable. This new allocation is never freed later, resulting in a memory leak. Using this version of the _bstr_t constructor avoids the issue by attaching the BSTR object to tmpbstr without a call to SysAllocString. For more information on this issue, see _bstr_t::_bstr_t (reference available in the C++ Language Reference section of the Visual C++ Documentation).

The problem is that explanation is wrong. My speculation: Most probably one person (senior programmer?) found memory leak in documentation, fixed it and told another person (junior programmer?) to update documentation. And that second person got it wrong. First: _bstr_t constructor _bstr_t::_bstr_t() does not allocate memory. Second: if it were allocating, then it would be freed, see the code below:
_bstr_t& _bstr_t::operator=(const wchar_t* s)
{
    if (s == NULL || ...)
    {
        _Free();
        m_Data = new Data_t(s);

And yes, _Free does exactly that. It frees m_Data if it contains something, in our case as I noted above, it points to 0x00000000;

operator=(const wchar_t* s) is exactly what is called in my case – Unicode compile.

Again, the code in Microsoft article leaks memory as comment says, but it does not leak as it is described. It leaks because memory allocated by m_pObject1->get_ObjectString is not freed.

In the end I found my memory leak. It was similar problem, I needed to call _bstr_t constructor with FALSE as second argument. From MSDN: If false, the bstr argument is attached to the new object without making a copy by calling SysAllocString.

So be careful playing with BSTRs.

2011 links no. 2

Stack Overflow profiler open sourced: Profiling your website like a true Ninja.

Smaller is Faster (and Safer Too). Chrome team have just started using a new compression algorithm called Courgette to make Google Chrome updates small. Read more.

Ask Amir Taaki About Bitcoin. From Slashdot.

The Four Stages of NTFS File Growth from Windows Server Core Team.

Some articles from CodeProject:

Rosa Golijan writes about what happens on the Internet every 60 seconds.

The Biggest Changes in C++11 (and Why You Should Care) by Danny Kalev.

Are You Too Good For Code Reviews? Articles and discussion in Slashdot.

Google’s Swiffy converts Flash SWF files to HTML5.

Have you wondered whether WordPress can handle high-volume traffic? High Traffic Tips For WordPress.

The most detailed story about Stuxnet: How Digital Detectives Deciphered Stuxnet, the Most Menacing Malware in History.

How to build your own 135TB RAID6 storage pod for $7,384 from extremetech.com.

Investigation: Is Your SSD More Reliable Than A Hard Drive? from tomshardware.com.

pdf.js is a technology demonstrator prototype to explore whether the HTML5 platform is complete enough to faithfully and efficiently render the ISO 32000-1:2008 Portable Document Format (PDF) without native code assistance. From Dr. Andreas Gal.

Setup Project shows ‘WARNING: Could not find prerequisite’ under Visual Studio 2010

Visual Studio Installer (MSI) warning:
WARNING: Could not find prerequisite '.NET Framework 2.0 (x86)' in path 'C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\'

or

WARNING: Could not find prerequisite '.NET Framework 2.0 (x86)' in path 'C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\'

The result is that automatic downloading of prerequisites does not work any more. This is caused by fact, that Visual Studio 2010 does not include:

  • .NET Framework 2.0
  • .NET Framework 3.0
  • .NET Framework 3.5 w/o SP1

There is discussion about this issue in VS2010 forum – Deployment project breaks on VS 2010 upgrade.

The suggested workaround is to use .NET Framework 3.5 SP1 Client Profile Prerequisite form available prerequisites under Setup project properties. This is some lightweight version of Microsoft .NET Framework.

If for some reason you do not want to use v3.5 framework, like, you do not want to force clients to download extra megabytes, you can copy needed Prerequisites from your Visual Studio 2008 folder.

From
"C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\"
to
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\"

under x64 bit Windows, or if you have 32-bit Windows version, use the following path:
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\"
to
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\"

Folders:

  • DotNetFX is .NET Framework 2.0
  • DotNetFX30 is .NET Framework 3.0
  • DotNetFX35 is .NET Framework 3.5 w/o SP1

P.S. Do not forget a proper testing!