su**************@gmail.com wrote:
We do suspect that there is a leak occurring during at the time the
no, but you might have a leak somewhere else, as you apparently do not
understand some things about _bstr_t and BSTR. And you have other
problems, described below.
const string FMLMsgProxy::getMsg ()
{
BSTR bstrMsg = m_pFINMsg->getMsg();
_bstr_t bstrtMsg(bstrMsg); //Code breaks here
I assume that getMsg (as called above) is actually wrapper provided by
compiler COM support, that is #import and accompanying *.tlh and *.tli
files. The wrapper funtion returns temporary object of type _bstr_t .
Just after initialization of BSTR bstrMsg this temporary object is
destroyed, and memory pointed by bstrMsg is freed by _bstr_t destructor.
Thus in next line bstrMsg is just a dangling pointer. This is why you
have crash.
Instead you should just use:
_bstr_t bstrtMsg = m_pFINMsg->getMsg();
If, on the other hand, getMsg() is not a wrapper and is *really*
returning a BSTR (not _bstr_t ), then you have a memory leak (but then
program wouldn't crash). Initialization of _bstr_t from BSTR will make a
copy and NOT take ownership of the string, unless you pass false as
second argument of constructor (that is fCopy, as documented in MSDN) -
in which case _bstr_t will take ownership of returned BSTR. If you just
use implicit conversion from BSTR to _bstr_t, you actually make a copy
of BSTR returned by COM function (instead of taking ownership), probably
no-one will free this BSTR and you have a leak.
STDMETHODIMP CFINMsg::getMsg(BSTR * o_Msg)
{
--------------------------------
-----------------------------
*o_Msg = m_OGMsg.copy(); //m_OGMsg is declared as _bstr_t
return S_OK;
If your function is returning a string (that is "[OUT, RETVAL] BSTRT *"
), you should pass ownership of _bstr_t . For this operation use
Detach(), not copy(). It's not that copy() or copy(true) are bad (they
aren't), but if you happen to call by mistake copy(false) or just
perform implicit converion from _bstr_t to BSTR, you will again end up
with dangling pointer. On the other hand, copy(true) is safe, but is
also wasting CPU cycles, as it allocates new string unnecessarily.
Obviously, caller of your function is resposible for freeing BSTR
returned as [OUT, RETVAL], but this is mandated by COM and provided by
COM wrappers (that is #import , *.tlh and *.tli files) so you do not
have to worry - if you use these COM wrappers properly.
I suggest that you buy this book
http://www.amazon.com/gp/product/0735611270/ (and I mean this one, not
any other - it's out of print, but there are still copies available) and
read first 3 chapters very, very carefully. At least twice. You would
benefit from other good books on COM, too.
B.
PS. some samples:
#include <comdef.h>
// fragile, caller might leak returned BSTR
BSTR foo() {_bstr_t t = L"foo"; return t.Detach();}
// fragile and unnecessary overhead making a copy
BSTR bar() {_bstr_t t = L"bar"; return t.copy();}
// very bad, returning dangling pointer
BSTR boo() {_bstr_t t = L"boo"; return t.copy(false);}
// very bad, just like boo, as operator BSTR is equiv. to copy(false)
BSTR bam() {_bstr_t t = L"bam"; return t;}
// reliable, like code provided by COM wrappers
_bstr_t bow() {_bstr_t t = L"bow"; return t;}
int main()
{
_bstr_t t(foo(), false); // OK, but fragile
_bstr_t t1 = bar(); // memory leak!
_bstr_t t2 = boo(); // crash!
_bstr_t t3 = bam(); // crash!
_bstr_t t4 = bow(); // OK and reliable
BSTR t5 = bow(); // potential trap ...
_bstr_t t6 = t5; // ... and crash!
}
obviusly, actual crash might or might not happen, depending on compiler
version, compilation options, sorrounding code etc - using dangling
pointer is always bad, however it may not always result in immediate
crash - often you will just see "bad" results, and sometimes you will
not even notice that you have a problem. This especially applies to
small sample app. that actually does nothing, just like the one above.