Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

When to use SysFreeString on a BSTR?

Posted on 1998-07-13
4
Medium Priority
?
4,401 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
0
Comment
Question by:rcasiple
  • 2
  • 2
4 Comments
 
LVL 11

Expert Comment

by:mikeblas
ID: 1167622
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

0
 
LVL 3

Accepted Solution

by:
Norbert earned 100 total points
ID: 1167623
First Reading the online help SetSasString will not wor in your case because it is used to set a BSTR not to get it:
CString::SetSysString

BSTR SetSysString( BSTR* pbstr ) const;

Return Value

The new string.

Parameters

pbstr   A pointer to a character string.

Remarks

Reallocates the BSTR pointed to by pbstr and copies the contents of the CString object into it, including the NULL character. The value of the BSTR referenced by pbstr may change. The function throws a CMemoryException if insufficient memory exists.

This function is normally used to change the value of strings passed by reference for OLE Automation.

Now to your problem:
I have figured out for my self - that means may be I am not right- that BSTR should be freed.
I believe that the writer about SysFreeString only had a look from C++ to VB where VB will delete the string.
But you can simple try it:
make a app that as fast as possible gets a string in a endless loop and watch the memory.
It can may be done by system monitor to watch free memory, size of swap file, used inside swapfile - Sorry I have a German version and I do not know the Exact translations used by sysmon.
If free mmory continuesly shrinks and Swapfile grows you must use SysFreeString
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1167624
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


0
 
LVL 3

Expert Comment

by:Norbert
ID: 1167625
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

0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

972 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question