CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jul 2005
    Posts
    85

    stl::string::c_str() return is valid after the string is deleted??

    Code:
    const char* foo(const char* str)
    {  string newStr(str) ;
       return newStr.c_str() ;
    }
     
    main()
    {  const char* str=foo("abcdefg") ;
    }
    Is that valid??
    I mean, what happens with the array of char returned by c_str() after he string is deleted??
    Last edited by Get_Free; July 24th, 2005 at 07:32 PM.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: stl::string::c_str() return is valid after the string is deleted??

    Quote Originally Posted by Get_Free
    Code:
    const char* foo(const char* str)
    { string newStr(str) ;
     return newStr.c_str() ;
    }
     
    main()
    { const char* str=foo("abcdefg") ;
    }
    Is that valid??
    No.
    I mean, what happens with the array of char returned by c_str() after he string is deleted??
    It probably goes up in smoke.

    You can return an object that has proper copy semantics (such as std::string), but not pointers (or references) to local variables. The c_str() returns a pointer for that particular string object, but that string object gets destroyed on return, therefore the data pointed to is also destroyed (or even if it isn't, it isn't valid to access that data).

    If you return pointers to local variables, then the behavior is undefined if you try to access that pointer.

    Note that you can return string objects, since std::string knows how to copy itself.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 24th, 2005 at 07:41 PM.

  3. #3
    Join Date
    Jul 2005
    Posts
    85

    Re: stl::string::c_str() return is valid after the string is deleted??

    That means that c_str() does not create an array of char but just point to the same actual string content??

    And... that means that several calls to c_str() will return the same pointer??
    Last edited by Get_Free; July 24th, 2005 at 08:12 PM.

  4. #4
    Join Date
    Apr 2004
    Location
    Canada
    Posts
    1,342

    Re: stl::string::c_str() return is valid after the string is deleted??

    Quote Originally Posted by Get_Free
    That means that c_str() does not create an array of char but just point to the same actual string content??

    And... that means that several calls to c_str() will return the same pointer??
    The behaviour of c_str() is implementation defined. It may return a pointer to the actual string content, or it may not. However, if c_str() does create a char array that contains a copy of a string, that char array will also be deleted when the string object goes out of scope, so you can't use it after that point. Your code produces undefined behaviour. It may have happened to work because you were lucky, but it's certainly not safe. As Paul McKenzie suggested, you should return the std::string object itself from the function.
    Old Unix programmers never die, they just mv to /dev/null

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: stl::string::c_str() return is valid after the string is deleted??

    c_str() does what it's stated to do -- that is return a const char *. Where that memory is depends on the implementation. Sure, if the string is reference-counted, the pointer may indeed exist outside of the function call. But again, that is if the string is reference counted -- you shouldn't assume that it is.

    The bottom line is that the string you're returning is destroyed. Once the object is destroyed, the data that comprised that object can no longer be relied on. You are attempting to access contents of an object that no longer exists.

    Why not just return the std::string?

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: stl::string::c_str() return is valid after the string is deleted??

    std::string is not guaranteed to have a contiguous buffer but the call to c_str() is guaranteed to return one. Although c_str() is a const function, i.e. it is not meant to change std::string, it is possible that (and likely that) in any implementation of std::string it will use a mutable buffer or a const_cast so that, in fact, c_str() would change the internal layout if it is not already contiguous. (Similarly the call to data(), although that call does not guarantee an extra '\0' character at the end of the buffer).

    Note that the danger of returning std::string comes only when you are using a DLL or shared-object library that needs to return a string. I have my own wrapper portable_string for that (which is an immutable string). It uses a custom deleter for a shared_ptr (and I will write an article on it someday I hope).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured