std:string causing memory leak
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/05/2012 at 03:27, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 13
Platform: Mac OSX ;
Language(s) : C++ ;---------
Hi guys,I'm getting a whole lot of memory leak warnings like after using std:str a number of times in a function. It seams like they are not destroyed after leaving the function, which afaik they should be.
std::string dname = bc->GetFilename(FILENAME_CACHEDIR).GetString().GetCStringCopy();
Since there is no destructor for std::str that I know of, any idea how to free the memory?
Thx,
Michael -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/05/2012 at 06:29, xxxxxxxx wrote:
Hi, the constructor of std::string copies the passed array internally so it doesn't take over the ownership.
You have to free the array returned by GetCStringCopy after you passed it to the constructor.Also see: http://www.cplusplus.com/reference/string/string/string/
std::string ( const char * s ); Content is initialized **to a copy of the string** formed...
Cheers, Sebastian
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/08/2012 at 01:49, xxxxxxxx wrote:
_> You have to free the array returned by GetCStringCopy after you passed it to the constructor.
_How are we supposed to free the array? GeFree()? Maybe I'm just blind, but I couldn't find the information in the docs.
Thanks,
Nik _
_ -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/08/2012 at 02:54, xxxxxxxx wrote:
Unless you actually allocate the std::string on the heap, as shown in the example below, it will go out of scope from the stack and be freed automatically:
int MyUselessFunction() { // for some reason you feel the need to allocate that string on the heap std::string * mystring= new std::string("Just a string."); // ... // deallocate it - notice that in the real world you'd use a smart pointer delete mystring; return 42; }
What Sebastian is saying is that the C string returned by GetCStringCopy() has no owner and is only copied into the std::string. So you will need a CHAR* to capture ownership and free the C string after assigning it to the std::string:
CHAR* cstr = bc->GetFilename(FILENAME_CACHEDIR).GetString().GetCStringCopy(); std::string dname = cstr; GeFree(cstr);
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/08/2012 at 03:23, xxxxxxxx wrote:
You can also use AutoGeFree.
Filename fname = bc->GetFilename(FILENAME_CACHEDIR); AutoGeFree<const char> cstr = fname.GetString().GetCStringCopy(); std::string dname = cstr;
or may be this way ? EDIT: just corrected this function to work as expected.
inline void StringToSTDString(const String& str, std::string &out) { LONG len = str.GetCStringLen(); if(len>0){ out.reserve(len+1); str.GetCString(&out[0],len+1); out.resize(len); }else out.clear(); }
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/08/2012 at 03:30, xxxxxxxx wrote:
Originally posted by xxxxxxxx
What Sebastian is saying is that the C string returned by GetCStringCopy() has no owner and is only copied into the std::string. So you will need a CHAR* to capture ownership and free the C string after assigning it to the std::string:
CHAR* cstr = bc->GetFilename(FILENAME_CACHEDIR).GetString().GetCStringCopy(); std::string dname = cstr; GeFree(cstr);
Thank you, this is what I wanted to know.
@Remotion4D:
Thank you, too. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/08/2012 at 07:13, xxxxxxxx wrote:
I think using GetCStringCopy() is not a good idea.
It use unnecessary short living memory allocation.//this one is ~5 times slower. inline void C4DStringToSTDStringSLOW(const String& str, std::string &out) { if(str.Content()){ AutoGeFree<const char> cstr( str.GetCStringCopy() ); out = (cstr); }else{ out.clear(); } } inline void C4DStringToSTDString(const String& str, std::string &out) { LONG len = str.GetCStringLen(); if(len>0){ out.reserve(len+1); str.GetCString(&out[0],len+1); out.resize(len); }else out.clear(); } inline void STDStringToC4DString(const std::string& str, String &out) { LONG len = str.length(); if(len>0){ out.SetCString(&str[0],len); }else{ out = String(); } }
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/08/2012 at 07:32, xxxxxxxx wrote:
Well, one could simply use GetCString() and handle the CHAR* themselves (either as a heap allocation that is freed within a method or on the stack as a CHAR array). If you are certain of the maximum length that the string might be, you can easily use CHAR cstr[MAXCSTRLEN]; in a method (where MAXCSTRLEN is some predetermined value). In C++, the stack can be used as a sort of AutoAlloc() when the memory needed isn't too much. Items on the stack only exist while in scope and are automatically 'freed' when they leave scope.