STL string problem
-
Hello to everyone again: I am experiencing a troubling problem with stl strings. I will try to be as much precise as possible. I have this definition, as my DLL must work under WIN32 and WINCE
#ifdef _UNICODE #define __tstring std::wstring #else #define __tstring std::string #endif
One object (CContainer) has to build an string with different information obtained from a structure.const TCHAR* CContainer::GetCurrentCommandText() { CCommands::LPCOMMAND pCommand = GetCurrentCommand(); __tstring sReturn; sReturn.clear(); if (pCommand) { CCommandToTextConvert* pText; pText= new CCommandToTextConvert(pCommand); sReturn.append(pText->GetSVOrigin()); sReturn.append(pText->GetSVDestination()); }
GetSVOrigin and GetSVDestination have a similar code. I'll show GetSVOrigin:const TCHAR* CCommandToTextConvert::GetSVOrigin() const { __tstring s; s.clear(); if (m_pCommand->dLong > 0) { s.append(_T("Origin: ")); s.append(m_pCommand->sOrigin); } //Here the string is correct, someting like "Origin: main street" return s.c_str(); //But the function returns something like "@X#R" (different each time) }
The problem, as mentioned in the code is that when returning, the string gets spoilt. If I make s.c_str() before returning, the result is right. As a result, when trying to append the strings returned by the functions, as each one is wrong, the result is wrong^2 I also tried to doconst TCHAR* sFoo; sFoo= new TCHAR[200]; sFoo = s.c_str(); return sFoo;
But the problem remains the same What on earth can be the problem? Answers will be really welcomed. José M Castellanos. Troubled rookie programmer :wtf: -
Hello to everyone again: I am experiencing a troubling problem with stl strings. I will try to be as much precise as possible. I have this definition, as my DLL must work under WIN32 and WINCE
#ifdef _UNICODE #define __tstring std::wstring #else #define __tstring std::string #endif
One object (CContainer) has to build an string with different information obtained from a structure.const TCHAR* CContainer::GetCurrentCommandText() { CCommands::LPCOMMAND pCommand = GetCurrentCommand(); __tstring sReturn; sReturn.clear(); if (pCommand) { CCommandToTextConvert* pText; pText= new CCommandToTextConvert(pCommand); sReturn.append(pText->GetSVOrigin()); sReturn.append(pText->GetSVDestination()); }
GetSVOrigin and GetSVDestination have a similar code. I'll show GetSVOrigin:const TCHAR* CCommandToTextConvert::GetSVOrigin() const { __tstring s; s.clear(); if (m_pCommand->dLong > 0) { s.append(_T("Origin: ")); s.append(m_pCommand->sOrigin); } //Here the string is correct, someting like "Origin: main street" return s.c_str(); //But the function returns something like "@X#R" (different each time) }
The problem, as mentioned in the code is that when returning, the string gets spoilt. If I make s.c_str() before returning, the result is right. As a result, when trying to append the strings returned by the functions, as each one is wrong, the result is wrong^2 I also tried to doconst TCHAR* sFoo; sFoo= new TCHAR[200]; sFoo = s.c_str(); return sFoo;
But the problem remains the same What on earth can be the problem? Answers will be really welcomed. José M Castellanos. Troubled rookie programmer :wtf:Jose M Castellanos wrote: //Here the string is correct, someting like "Origin: main street" return s.c_str(); //But the function returns something like "@X#R" (different each time) You are returning a const TCHAR* to a local variable. After the function exits, that memory is freed, and your pointer is pointing to garbage. Jose M Castellanos wrote: const TCHAR* sFoo; sFoo= new TCHAR[200]; sFoo = s.c_str(); return sFoo; You are still returning a pointer to a local variable here (+ leaking 200 * sizeof(TCHAR) bytes). Jose M Castellanos wrote: Answers will be really welcomed Potential memory leaks aside, if you want this to work you have to copy the string to the buffer you create:
_tcsncpy(sFoo, s.c_str(), 200);
though changing you interface to something like:bool CCommandToTextConvert::GetSVOrigin(TCHAR* buff, int& size) const
where you allocate (and deallocate) the memory outside the function is a better solution. Note: You will still have to copy the string tobuff
. HTH Jonas “Our solar system is Jupiter and a bunch of junk” - Charley Lineweaver 2002 -
Jose M Castellanos wrote: //Here the string is correct, someting like "Origin: main street" return s.c_str(); //But the function returns something like "@X#R" (different each time) You are returning a const TCHAR* to a local variable. After the function exits, that memory is freed, and your pointer is pointing to garbage. Jose M Castellanos wrote: const TCHAR* sFoo; sFoo= new TCHAR[200]; sFoo = s.c_str(); return sFoo; You are still returning a pointer to a local variable here (+ leaking 200 * sizeof(TCHAR) bytes). Jose M Castellanos wrote: Answers will be really welcomed Potential memory leaks aside, if you want this to work you have to copy the string to the buffer you create:
_tcsncpy(sFoo, s.c_str(), 200);
though changing you interface to something like:bool CCommandToTextConvert::GetSVOrigin(TCHAR* buff, int& size) const
where you allocate (and deallocate) the memory outside the function is a better solution. Note: You will still have to copy the string tobuff
. HTH Jonas “Our solar system is Jupiter and a bunch of junk” - Charley Lineweaver 2002Thank you Jonas: You're right, the variable is a local one and it's destroyed. I didn't realize before because these functions are adaptations of a previous one in which the returned variable was a member variable. Thus the m_string.c_str() was not destroyed after exiting. Sometimes, trees don't let you see the forest .... that's what happened this time. My solution finally has been adding a member variable that is the one returned.
m_sText.clear(); m_sText.append(s); return m_sText.c_str();