We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

When to use SysFreeString on a BSTR?

rcasiple
rcasiple asked
on
Medium Priority
5,068 Views
Last Modified: 2012-06-21
We are developing 32 bit Automation components using VB 5.0 and MFC ClassWizard.  On our components we have several accessor methods that manipulate a CString and then return a BSTR back to the consumer by using the AllocSysString() method:

BSTR SomeClass::getSomeString()
{
   CString strResult;

   strResult = "Something.."

   return ( strResult.AllocSysString();
}

The consumer would use a smart pointer to a SomeClass instance to access this function like this:

{
// create smart pointer
   _DSomeClassPtr   anObject;
anObject.CreateInstance(SOME_CLASS_NAME);

// get the string
BSTR  aBSTRString;
aBSTRString = anObject->getSomeString()

//  do something with it, like convert back to a CString
CString strResult;
strResult = CString(aString);

// Free the BSTR... Is this necessary?
::SysFreeString(aBSTRString)
}

BoundsChecker flags an error indicating the SysFreeString is freeing memory in a bad address location.  

The MSDN indicates that you should use ::SysFreeString in the rare case that you need to deallocate the returned string.  Should we not be using this function on BSTR's converted from CStrings using the CString::AllocSysString method?

Thanks
-R
Comment
Watch Question

Commented:
Exactly what constructor are you trying to invoke when you pass a BSTR to CString::CString()?  CString has no BSTR constructor.  You should be calling CString::SetSysString().

B ekiM

Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Commented:
You're all wet on this one, Norbert.

I suggested using SetSysString() instead of the incorrect constructor invocation rcaspile was using.  It's not a solution to the question he posted, but the code he posted is dead wrong and he needs to know that.

Second, a system string has a life just like any other allocated memory that's passed from module to module. The caller must know if the callee is going to do free the string, or if the callee is going to copy the string.  Normally, in almost all circumstances, OLE Automation interfaces will have the callee own the string--therefore, the callee is responsible for freeing the string.

Your loop test is orthogonal. It's just allocating memory over and over. Of course, since nobody is being called, the ownership of the memory doesn't change. Since the loop doesn't free, the memory is leaked.

B ekiM


Commented:
Mikeblas: The memory is leaked only if the client (the callee) does not free it. If you are using VB as Client VB will free the memory inside its runtime. If you use C++ as client you have to free it your self.

Again about SetSysString:
I know that you did not give a solution for the problem but as I read the online help SetSysString is used to fill a BSTR with the contens of a CString not to fill a CString with the contens of a BSTR so what you suggest will not work absolutely
The best way to convert a BSTR to a CString is as I think the function
void AFXAPI AfxBSTR2CString(CString* pStr, BSTR bstr);
There is no description in online help.
the prototype is in AFXPRIV2.h and the implementation in OLECNVRT.CPP.
AFXPRIV2.H is included by AFXPRIV.h

Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.