views:

555

answers:

2

I have read that the following code causes memory leak. But did not understand why.

CComBSTR str;
pFoo->get_Bar(&str);
pFoo->get_Baf(&str);

How does it cause a leak when we are not allocating anything?

+2  A: 

This Microsoft page is probably the where you read about it:

http://msdn.microsoft.com/en-us/library/bdyd6xz6.aspx

Memory Leak Issues

Passing the address of an initialized CComBSTR to a function as an [out] parameter causes a memory leak.

The CComBSTR object is allocating memory internally. Evidently there are cases where it doesn't release it.

Mark Ransom
+5  A: 

It leaks because get_Bar() and get_Baf() don't know that you're using a CComBSTR.

When you take the address of a CComBSTR what you're actually passing to the underlying object is a pointer to the CComBSTR's BSTR member.

Breaking down the sequence:

CComBSTR str;

This initializes the internal BSTR to NULL.

pFoo->get_Bar(&str);

get_Bar() sees a BSTR* and fills it with actual data. Like this:

HRESULT get_Bar(BSTR* arg) { *arg = SysAllocString(L"My String"); }

Now the internal BSTR of str is a real BSTR. When CComBSTR goes out of scope it will delete the str member.

Now if you call get_Baf() on &str the problem is that the CComBSTR doesn't know that you are changing the string. So you call get_Baf() like this:

HRESULT get_Baf(BSTR* arg) { *arg = SysAllocString(L"My String"); }

Now get_Baf() has overwritten the original value of str's internal BSTR without anyone freeing the data that was allocated by get_Bar().

Ta da - Memory leak.

Aaron
So if we have just the first two linesCComBSTR str;pFoo->get_Bar(then it wont cause a leak and there is no need to Empty it right.
Julian
That is correct.
Aaron
Kim Gräsman

related questions