Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Converting BSTR to Char does this function look good?

Status
Not open for further replies.

Horist

Programmer
Oct 19, 2001
3
US
Ok, first, a bit of background
The software I'm working on now has a web front end, but enters data and queries data from a Remedy server.

Now, all of the functions to submit and query work flawlessly, however, in my first version of the ActiveX DLL I had a memory leak... The Inetinfo process on our production box would consume 300MB of memory and die.

I found that the problem was My original function for converting BSTR to Char was flawed in that I did not deallocate memory that I allocated.

Now here's my second version, I want to make sure it looks Kosher before I place it in production.

char* CMARS::ConvertBSTRtoCHAR(BSTR BSTRString)
{
_bstr_t *tempbstr = new _bstr_t;
tempbstr->Assign(BSTRString);
char *string = 0;
string = new char[tempbstr->length()+1];
strcpy(string,tempbstr->operator const char *());
delete tempbstr;
tempbstr=0;
return string;
}

I store the returned character string pointer in a linked list, and when the function that uses the convertBSTRtoCHAR is done, it deallocates all the memory. So far it looks good.

So question is: Does this function look good? (for taking a BSTR variable and converting to a character pointer)
And, is there any software I can use to determine if there is still a memory leak?

Thanks,
Mike
 
Hi Mike,

You could use OLE2A macro for the same.
For checking memory leaks Use Numega BoundsChecker.

Here are some conversion lines which I prefer to use.
I don't know any drawbacks.

USES_CONVERSION; // this macro is required for OLE2A macro

BSTR str1;
BSTR str2;
BSTR str3;
char ch[10]="ESG";
wchar_t wch[10];

str1=SysAllocStringLen(L"Testing",20);
str2=SysAllocString(str1);
//when str2=str1 is done both ptrs will be refering to the same mem location
// str2 =str1
//char to bstr
str3= SysAllocString(A2BSTR((const char *)ch )); // convert ansi to BSTR

//bstr to char
char *cp= OLE2A(str3); //convert BSTR to ansi

 
Hi Mike,

Unfortunately there's a big problem using OLE2A - it allocates the storage on the stack (via _alloca). This is of course great if you want to temporarily convert results without allocating on the heap, but doesn't help much in your case.

Also, although I guess your routine works, it's a little convoluted, there's really no need to allocate a temp _b_str on the heap und use all those ->. The following code does as well:

char* ConvertBSTRtoCHAR(_bstr_t bstr)
{
char* string = new char[bstr.length()+1];
strcpy(string,(const char*)bstr);
return string;
}

called like this:

BSTR b;
...
char* pc = ConvertBSTRtoCHAR(b);
cout << pc << endl;
delete [] pc;

However, it's always rather dangerous returning pointers to items on the heap (Windows hardly ever does it) since if this is used in an expression, which is easily done, for example:
cout << ConvertBSTRtoCHAR(b) << endl;

Who's going to free the storage? It's a lot safer to use a ** parameter

void ConvertBSTRtoCHAR(_bstr_t bstr, char**ppc)
{
*ppc= new char[bstr.length()+1];
strcpy(*ppc,(const char*)bstr);
return;
}

and call it like

char* pc;
ConvertBSTRtoCHAR(b,&pc);
delete [] pc;

so that this mistake can't occur.

Of course, if you wanted not to pass a _bstr_t as parameter for whatever reason you can write the routine like this:

void ConvertBSTRtoCHAR(BSTR bstr, char**ppc)
{
_bstr_t _bstr(bstr);
*ppc= new char[_bstr.length()+1];
strcpy(*ppc,(const char*)_bstr);
return;
}
:) Hope that this helped! ;-)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top