C Drozdowski
C Drozdowski

Reputation: 13

C++ Calling Functions in a COM DLL Possible Memory Leak

I created a C++ console app using VC++ 2017. It makes a number of calls over time to retrieve data from a 3rd party COM DLL. I use COM classes like CComSafeArray and CComVariant that manage their own freeing.

Over time I observe that the memory for my App steadily increases in Task Manager after each COM call.

I have used the CRT library (https://learn.microsoft.com/en-us/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019) to try to detect memory leaks but it indicates I have none.

My question(s) is/are:

  1. Does COM in general do it's own memory management that the CRT library cannot detect but is tied to my process?
  2. If #1 is the case, are there tools available to detect COM memory leaks?
  3. If #1 is the case, is there a way to garbage collect COM memory?

Thanks for your consideration.

Edit 4-19-2019 I have found out that the COM Dll returns VARIANT's and BSTR's for function call results. I am assigning them variously to _variant_t and _bstr_t as applicable to provide automatic cleanup (theoretically). For example.

_variant_t v = GetSomeVariant();
_bstr_t b = GetSomeString();

The DLL does not use CoTaskMemAlloc but it does use SysAllocString to generate the BSTRs.

Upvotes: 0

Views: 391

Answers (2)

MSalters
MSalters

Reputation: 179819

_bstr_t b = GetSomeString();

Presumably, that is BSTR GetSomeString();. Which to the compiler meanswchar_t* GetSomeString ; BSTR tells you that it uses COM semantics but the compiler doesn't know that. And those semantics are that you call SysFreeString.

_bstr_t::_bstr_t( wchar_t* str ) copies str. Yes, _bstr_t::~_bstr_t will then call SysFreeString, but it does so on the copy. You needed to call SysFreeString on the BSTR GetSomeString();.

The solution is _bstr_t::_bstr_t( BSTR bstr , bool fCopy ) with fCopy=false. Per MSDN:

This constructor is used by wrapper functions in the type library headers to encapsulate and take ownership of a BSTR that is returned by an interface method.

For VARIANT, see _variant_t::_variant_t(VARIANT& varSrc, bool fCopy);. Same idea.

Upvotes: 0

J.R.
J.R.

Reputation: 1978

COM does not use any automated garbage collection; everything has to be accounted for although there are helper classes available that take care of reference counting.

The convention in COM is that, if the called method allocates some memory then the caller has to free it with CoTaskMemFree. You may want to check your code for the DLL methods that you call and if they return anything in a buffer that was allocated by the DLL then you'll need to free that buffer by calling CoTaskMemFree.

See https://learn.microsoft.com/en-us/windows/desktop/learnwin32/memory-allocation-in-com

More details here: https://learn.microsoft.com/en-us/windows/desktop/com/memory-management-rules

Upvotes: 1

Related Questions