10100111001
10100111001

Reputation: 777

BSTR memory leak in atldbsch.h - what to do?

I am running Deleaker application to find and fix memory leaks in an application. Now, it finds a lot of BSTR leaks with roots in the Open()-function of the Microsoft CRestrictions class (atldbsch.h file).

If one looks there one can notice that it takes 7 LPCTSTR parameters, which are then used like this:

pVariant = m_pvarRestrictions + 1;
.
.
pVariant->bstrVal = ::SysAllocString(T2COLE_EX_DEF(lpszParam1));

This is done for all seven such parameters (where the number 1 is increased every time).

The destructor is simply doing

delete[] m_pvarRestrictions;

but the BSTRs allocated via ::SysAllocString() are never freed though via calls to ::SysFreeStr()

Am I missing something or is there a leak, and in that case how should it be handled in this case?

Upvotes: 0

Views: 369

Answers (3)

Artem Razin
Artem Razin

Reputation: 1286

After checking the code I would say that no leaks here because m_pvarRestrictions is a pointer to array of CComVariant, and this array is deleted via delete[], so destructor for each CComVariant is called. CComVariant::~CComVariant() calls VariantClear that itself frees BSTR if this VARIANT contains it.

Then I've checked how Deleaker (version 3.0.66.0) works with CComVariant, here my code:

int _tmain(int argc, _TCHAR* argv[])
{
    CComVariant* v = new CComVariant(L"123");
    delete v;

    return 0;
}

No leaks are shown. Probably you've tried old version of Deleaker.

If I remove delete v, then I see two leaks: heap memory and BSTR.

Upvotes: 1

xMRi
xMRi

Reputation: 15365

Are you sure that you set the pVariant type also to VT_BSTR. This isn't shown in the code. If you don't set the type, this will cause a leak.

If pVariant is in fact a pointer to CComVariant this code should work:

*pVariant = T2COLE_EX_DEF(lpszParam1);

And in this case VT_BSTR type is set and the destruction will clean up the variant.

Upvotes: 0

reece
reece

Reputation: 8155

According to https://github.com/dpalma/sge/blob/master/3rdparty/atl/atldbsch.h, m_pvarRestrictions is defined as ATL::CComVariant *, so the ATL::CComVariant destructor should be cleaning up the BSTR variants (the code is correctly setting vt to VT_BSTR). That is, the CComVariant destructor calls CComVariant::Clear which calls VariantClear.

Thus, there should not be a memory leak here -- the code looks correct. It is likely an issue with Deleaker having problems detecting this pattern.

Upvotes: 0

Related Questions