Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    std:string causing memory leak

    Scheduled Pinned Locked Moved SDK Help
    8 Posts 0 Posters 522 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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 _
          _

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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);
            
            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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();
                  }  
                  
              
              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  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();
                      	}
                      }  
                      
                  
                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    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.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post