How to return a std::string.c_str()












23















I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.



const char * returnCharPtr()
{
std::string someString;

// some processing!.

return someString.c_str();
}


I have got a report from COVERITY tool that the above is not a good usage. I have googled and have found that the char pointer returned, would be invalidated as soon as someString meets its destruction.



Given this, how does one fix this issue? How to return char pointer accurately?



Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.










share|improve this question




















  • 1





    You can't return pointers to/of local objects. See this.

    – ApproachingDarknessFish
    Mar 11 '14 at 16:11






  • 8





    This sort of situation is a large part of the reason things like std::string was invented to start with. Almost anything you invent will nearly inevitably be either 1) a duplicate of what std::string already does, or 2) broken.

    – Jerry Coffin
    Mar 11 '14 at 16:29











  • @Mr.C64 Removing the [C] tag changed the meaning of the question. A C++/C interoperability question is VERY different from a C++ question, and would make returning a const char* far more valid. Do you have a good justification for removing the [C] tag?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:13











  • @user3210526 are you interoperating with C code? If so, how is the lifetime of the returned char* managed in the C code? If not, why tag your post with [C]?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:14
















23















I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.



const char * returnCharPtr()
{
std::string someString;

// some processing!.

return someString.c_str();
}


I have got a report from COVERITY tool that the above is not a good usage. I have googled and have found that the char pointer returned, would be invalidated as soon as someString meets its destruction.



Given this, how does one fix this issue? How to return char pointer accurately?



Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.










share|improve this question




















  • 1





    You can't return pointers to/of local objects. See this.

    – ApproachingDarknessFish
    Mar 11 '14 at 16:11






  • 8





    This sort of situation is a large part of the reason things like std::string was invented to start with. Almost anything you invent will nearly inevitably be either 1) a duplicate of what std::string already does, or 2) broken.

    – Jerry Coffin
    Mar 11 '14 at 16:29











  • @Mr.C64 Removing the [C] tag changed the meaning of the question. A C++/C interoperability question is VERY different from a C++ question, and would make returning a const char* far more valid. Do you have a good justification for removing the [C] tag?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:13











  • @user3210526 are you interoperating with C code? If so, how is the lifetime of the returned char* managed in the C code? If not, why tag your post with [C]?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:14














23












23








23


6






I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.



const char * returnCharPtr()
{
std::string someString;

// some processing!.

return someString.c_str();
}


I have got a report from COVERITY tool that the above is not a good usage. I have googled and have found that the char pointer returned, would be invalidated as soon as someString meets its destruction.



Given this, how does one fix this issue? How to return char pointer accurately?



Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.










share|improve this question
















I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.



const char * returnCharPtr()
{
std::string someString;

// some processing!.

return someString.c_str();
}


I have got a report from COVERITY tool that the above is not a good usage. I have googled and have found that the char pointer returned, would be invalidated as soon as someString meets its destruction.



Given this, how does one fix this issue? How to return char pointer accurately?



Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.







c++ string pointers c++11 return






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 11 '14 at 16:32









Mr.C64

28.3k1062119




28.3k1062119










asked Mar 11 '14 at 15:37









user3210526user3210526

115115




115115








  • 1





    You can't return pointers to/of local objects. See this.

    – ApproachingDarknessFish
    Mar 11 '14 at 16:11






  • 8





    This sort of situation is a large part of the reason things like std::string was invented to start with. Almost anything you invent will nearly inevitably be either 1) a duplicate of what std::string already does, or 2) broken.

    – Jerry Coffin
    Mar 11 '14 at 16:29











  • @Mr.C64 Removing the [C] tag changed the meaning of the question. A C++/C interoperability question is VERY different from a C++ question, and would make returning a const char* far more valid. Do you have a good justification for removing the [C] tag?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:13











  • @user3210526 are you interoperating with C code? If so, how is the lifetime of the returned char* managed in the C code? If not, why tag your post with [C]?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:14














  • 1





    You can't return pointers to/of local objects. See this.

    – ApproachingDarknessFish
    Mar 11 '14 at 16:11






  • 8





    This sort of situation is a large part of the reason things like std::string was invented to start with. Almost anything you invent will nearly inevitably be either 1) a duplicate of what std::string already does, or 2) broken.

    – Jerry Coffin
    Mar 11 '14 at 16:29











  • @Mr.C64 Removing the [C] tag changed the meaning of the question. A C++/C interoperability question is VERY different from a C++ question, and would make returning a const char* far more valid. Do you have a good justification for removing the [C] tag?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:13











  • @user3210526 are you interoperating with C code? If so, how is the lifetime of the returned char* managed in the C code? If not, why tag your post with [C]?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 20:14








1




1





You can't return pointers to/of local objects. See this.

– ApproachingDarknessFish
Mar 11 '14 at 16:11





You can't return pointers to/of local objects. See this.

– ApproachingDarknessFish
Mar 11 '14 at 16:11




8




8





This sort of situation is a large part of the reason things like std::string was invented to start with. Almost anything you invent will nearly inevitably be either 1) a duplicate of what std::string already does, or 2) broken.

– Jerry Coffin
Mar 11 '14 at 16:29





This sort of situation is a large part of the reason things like std::string was invented to start with. Almost anything you invent will nearly inevitably be either 1) a duplicate of what std::string already does, or 2) broken.

– Jerry Coffin
Mar 11 '14 at 16:29













@Mr.C64 Removing the [C] tag changed the meaning of the question. A C++/C interoperability question is VERY different from a C++ question, and would make returning a const char* far more valid. Do you have a good justification for removing the [C] tag?

– Yakk - Adam Nevraumont
Mar 11 '14 at 20:13





@Mr.C64 Removing the [C] tag changed the meaning of the question. A C++/C interoperability question is VERY different from a C++ question, and would make returning a const char* far more valid. Do you have a good justification for removing the [C] tag?

– Yakk - Adam Nevraumont
Mar 11 '14 at 20:13













@user3210526 are you interoperating with C code? If so, how is the lifetime of the returned char* managed in the C code? If not, why tag your post with [C]?

– Yakk - Adam Nevraumont
Mar 11 '14 at 20:14





@user3210526 are you interoperating with C code? If so, how is the lifetime of the returned char* managed in the C code? If not, why tag your post with [C]?

– Yakk - Adam Nevraumont
Mar 11 '14 at 20:14












10 Answers
10






active

oldest

votes


















19














What happens in this code is:



const char * returnCharPtr()
{
std::string someString("something");
return someString.c_str();
}



  1. instance of std::string is created - it is an object with automatic storage duration

  2. pointer to the internal memory of this string is returned

  3. object someString is destructed and the its internal memory is cleaned up

  4. caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior


The best solution: return an object :



std::string returnString()
{
std::string someString("something");
return someString;
}





share|improve this answer





















  • 3





    But why const? Now it can't be moved.

    – juanchopanza
    Mar 11 '14 at 15:48











  • @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

    – LihO
    Mar 11 '14 at 16:15











  • I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

    – Rapnar
    Sep 22 '15 at 14:09











  • 99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

    – siwmas
    Jul 13 '18 at 15:34











  • What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

    – Yuval
    Dec 24 '18 at 16:01





















10














In C++, the simplest thing to do is to just returna std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):



std::string returnSomeString()
{
std::string someString;

// some processing...

return someString;
}


If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.



// void SomeLegacyFunction(const char * psz)

// .c_str() called on the returned string, to get the 'const char*'
SomeLegacyFunction( returnSomeString().c_str() );


If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new), and return a pointer to that:



// NOTE: The caller owns the returned pointer, 
// and must free the string using delete !!!
const char* returnSomeString()
{
std::string someString;

// some processing...

// Dynamically allocate memory for the returned string
char* ptr = new char[someString.c_str() + 1]; // +1 for terminating NUL

// Copy source string in dynamically allocated string buffer
strcpy(ptr, someString.c_str());

// Return the pointer to the dynamically allocated buffer
return ptr;
}


An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:



void returnSomeString(char* destination, size_t destinationSize)
{
std::string someString;

// some processing...

// Copy string to destination buffer.
// Use some safe string copy function to avoid buffer overruns.
strcpy_s(destination, destinationSize, someString.c_str());
}





share|improve this answer



















  • 1





    It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

    – marsh
    Oct 12 '16 at 13:35






  • 1





    @marsh It is the caller's responsibility to check if he owns the returned pointer.

    – siwmas
    Jul 13 '18 at 15:36



















5














As this question is flagged C, do this:



#define _POSIX_C_SOURCE 200809L
#include <string.h>

const char * returnCharPtr()
{
std::string someString;

// some processing!.

return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
}


Do not forget to free() what the function returned if of no use anymore.






share|improve this answer


























  • I don't see the C flag, has it changed?

    – Yakk - Adam Nevraumont
    Mar 11 '14 at 18:53











  • @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

    – alk
    Mar 11 '14 at 19:37













  • Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

    – Tommaso Thea Cioni
    Jul 15 '18 at 17:24



















3














Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.



But if what you want is a C-string, how about...



const char * returnCharPtr()
{
std::string someString;

// some processing!.

char * new_string = new char[someString.length() + 1];

std::strcpy(new:string, someString.c_str());

return new_string;
}


But wait... that's almost exactly as returning a std::string, isn't it?



std::string returnCharPtr()
{
std::string someString;

// some processing!.

return new_string;
}


This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.



Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).



So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :



void returnCharPtr(std::string & someString)
{
// some processing!.
}


Or, again, if you want C-Strings, you need to watch out for the length of your string:



void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
{
// some processing!.
}





share|improve this answer





















  • 3





    Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

    – chris
    Mar 11 '14 at 16:13








  • 1





    You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

    – R. Martinho Fernandes
    Mar 11 '14 at 16:18











  • To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

    – Praetorian
    Mar 11 '14 at 16:19













  • Oh, my... I don't deserve to live D: I got it all backwards!

    – ArthurChamz
    Mar 11 '14 at 16:24











  • Thanks for all the corrections =)

    – ArthurChamz
    Mar 11 '14 at 16:27



















1














The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.



Stay with std::string.






share|improve this answer































    1














    Your options are:



    Return std::string



    Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.



    Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
    This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.



    Choose the first one; return std::string.
    It is by far the simplist and safest option.






    share|improve this answer































      1














      The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.



      Don't return .c_str() of string that could be destroyed before you use the returned char pointer.



      Instead of...



      const char* function()
      {
      std::string someString;
      // some processing!
      return someString.c_str();
      }

      //...

      useCharPtr(function());


      use



      std::string function()
      {
      std::string someString;
      // some processing!
      return someString;
      }

      //...

      useCharPtr(function().c_str());





      share|improve this answer































        1














        You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)



        void returnCharPtr(char* someString)
        {
        // some processing!
        if(someString[0] == 'A')
        someString++;
        }





        share|improve this answer





















        • 1





          This assumes the caller knows how long the string is going to be, which is most often not the case.

          – Praetorian
          Mar 11 '14 at 16:13



















        1














        If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.



        char* returnCharPtr() 
        {
        std::string someString;

        // some processing!.

        char* cp = new char[someString.length()+1];
        strcpy(cp, someString.c_str());
        return cp;
        }





        share|improve this answer































          1














          A solution which hasn't been evoked in the other answers.



          In case your method is a member of a class, like so:



          class A {
          public:
          const char *method();
          };


          And if the class instance will live beyond the usefulness of the pointer, you can do:



          class A {
          public:
          const char *method() {
          string ret = "abc";
          cache.push_back(std::move(ret));
          return cache.last().c_str();
          }
          private:
          vector<string> cache; //std::deque would be more appropriate but is less known
          }


          That way the pointers will be valid up till A's destruction.



          If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f22330250%2fhow-to-return-a-stdstring-c-str%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            10 Answers
            10






            active

            oldest

            votes








            10 Answers
            10






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            19














            What happens in this code is:



            const char * returnCharPtr()
            {
            std::string someString("something");
            return someString.c_str();
            }



            1. instance of std::string is created - it is an object with automatic storage duration

            2. pointer to the internal memory of this string is returned

            3. object someString is destructed and the its internal memory is cleaned up

            4. caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior


            The best solution: return an object :



            std::string returnString()
            {
            std::string someString("something");
            return someString;
            }





            share|improve this answer





















            • 3





              But why const? Now it can't be moved.

              – juanchopanza
              Mar 11 '14 at 15:48











            • @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

              – LihO
              Mar 11 '14 at 16:15











            • I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

              – Rapnar
              Sep 22 '15 at 14:09











            • 99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

              – siwmas
              Jul 13 '18 at 15:34











            • What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

              – Yuval
              Dec 24 '18 at 16:01


















            19














            What happens in this code is:



            const char * returnCharPtr()
            {
            std::string someString("something");
            return someString.c_str();
            }



            1. instance of std::string is created - it is an object with automatic storage duration

            2. pointer to the internal memory of this string is returned

            3. object someString is destructed and the its internal memory is cleaned up

            4. caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior


            The best solution: return an object :



            std::string returnString()
            {
            std::string someString("something");
            return someString;
            }





            share|improve this answer





















            • 3





              But why const? Now it can't be moved.

              – juanchopanza
              Mar 11 '14 at 15:48











            • @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

              – LihO
              Mar 11 '14 at 16:15











            • I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

              – Rapnar
              Sep 22 '15 at 14:09











            • 99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

              – siwmas
              Jul 13 '18 at 15:34











            • What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

              – Yuval
              Dec 24 '18 at 16:01
















            19












            19








            19







            What happens in this code is:



            const char * returnCharPtr()
            {
            std::string someString("something");
            return someString.c_str();
            }



            1. instance of std::string is created - it is an object with automatic storage duration

            2. pointer to the internal memory of this string is returned

            3. object someString is destructed and the its internal memory is cleaned up

            4. caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior


            The best solution: return an object :



            std::string returnString()
            {
            std::string someString("something");
            return someString;
            }





            share|improve this answer















            What happens in this code is:



            const char * returnCharPtr()
            {
            std::string someString("something");
            return someString.c_str();
            }



            1. instance of std::string is created - it is an object with automatic storage duration

            2. pointer to the internal memory of this string is returned

            3. object someString is destructed and the its internal memory is cleaned up

            4. caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior


            The best solution: return an object :



            std::string returnString()
            {
            std::string someString("something");
            return someString;
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 11 '14 at 16:11

























            answered Mar 11 '14 at 15:47









            LihOLihO

            32.8k772136




            32.8k772136








            • 3





              But why const? Now it can't be moved.

              – juanchopanza
              Mar 11 '14 at 15:48











            • @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

              – LihO
              Mar 11 '14 at 16:15











            • I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

              – Rapnar
              Sep 22 '15 at 14:09











            • 99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

              – siwmas
              Jul 13 '18 at 15:34











            • What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

              – Yuval
              Dec 24 '18 at 16:01
















            • 3





              But why const? Now it can't be moved.

              – juanchopanza
              Mar 11 '14 at 15:48











            • @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

              – LihO
              Mar 11 '14 at 16:15











            • I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

              – Rapnar
              Sep 22 '15 at 14:09











            • 99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

              – siwmas
              Jul 13 '18 at 15:34











            • What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

              – Yuval
              Dec 24 '18 at 16:01










            3




            3





            But why const? Now it can't be moved.

            – juanchopanza
            Mar 11 '14 at 15:48





            But why const? Now it can't be moved.

            – juanchopanza
            Mar 11 '14 at 15:48













            @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

            – LihO
            Mar 11 '14 at 16:15





            @juanchopanza: Well, it depends on how it's going to be used. But yeah, I admit that simple std::string will do better + it will be more flexible too.

            – LihO
            Mar 11 '14 at 16:15













            I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

            – Rapnar
            Sep 22 '15 at 14:09





            I have a situation where returnString().c_str() == 0 (returned string is "m") but if I save the return value then call c_str() on the temp it works. Ideas?

            – Rapnar
            Sep 22 '15 at 14:09













            99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

            – siwmas
            Jul 13 '18 at 15:34





            99% of the cases you should return std::string, but the most voted answer should cover the case where char* is actually needed as return type (this is what the question asks anyway). Mr.C64 answer looks more complete to me.

            – siwmas
            Jul 13 '18 at 15:34













            What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

            – Yuval
            Dec 24 '18 at 16:01







            What about the case when one would like to override the what() virtual function from std::exception , virtual const char* what()const throw() override; if one would like to return anything that isn't a literal string, i.e returning some extra relavent run time information string, char* would be needed. The only solution I seem to think about is making a static std::string and then c_str() wouldn't be returned as a dangling pointer, but it seems as a too ugly of a solution, and frankly I hate the idea of static life duration for a string that only needs to be printed once.

            – Yuval
            Dec 24 '18 at 16:01















            10














            In C++, the simplest thing to do is to just returna std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):



            std::string returnSomeString()
            {
            std::string someString;

            // some processing...

            return someString;
            }


            If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.



            // void SomeLegacyFunction(const char * psz)

            // .c_str() called on the returned string, to get the 'const char*'
            SomeLegacyFunction( returnSomeString().c_str() );


            If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new), and return a pointer to that:



            // NOTE: The caller owns the returned pointer, 
            // and must free the string using delete !!!
            const char* returnSomeString()
            {
            std::string someString;

            // some processing...

            // Dynamically allocate memory for the returned string
            char* ptr = new char[someString.c_str() + 1]; // +1 for terminating NUL

            // Copy source string in dynamically allocated string buffer
            strcpy(ptr, someString.c_str());

            // Return the pointer to the dynamically allocated buffer
            return ptr;
            }


            An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:



            void returnSomeString(char* destination, size_t destinationSize)
            {
            std::string someString;

            // some processing...

            // Copy string to destination buffer.
            // Use some safe string copy function to avoid buffer overruns.
            strcpy_s(destination, destinationSize, someString.c_str());
            }





            share|improve this answer



















            • 1





              It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

              – marsh
              Oct 12 '16 at 13:35






            • 1





              @marsh It is the caller's responsibility to check if he owns the returned pointer.

              – siwmas
              Jul 13 '18 at 15:36
















            10














            In C++, the simplest thing to do is to just returna std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):



            std::string returnSomeString()
            {
            std::string someString;

            // some processing...

            return someString;
            }


            If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.



            // void SomeLegacyFunction(const char * psz)

            // .c_str() called on the returned string, to get the 'const char*'
            SomeLegacyFunction( returnSomeString().c_str() );


            If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new), and return a pointer to that:



            // NOTE: The caller owns the returned pointer, 
            // and must free the string using delete !!!
            const char* returnSomeString()
            {
            std::string someString;

            // some processing...

            // Dynamically allocate memory for the returned string
            char* ptr = new char[someString.c_str() + 1]; // +1 for terminating NUL

            // Copy source string in dynamically allocated string buffer
            strcpy(ptr, someString.c_str());

            // Return the pointer to the dynamically allocated buffer
            return ptr;
            }


            An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:



            void returnSomeString(char* destination, size_t destinationSize)
            {
            std::string someString;

            // some processing...

            // Copy string to destination buffer.
            // Use some safe string copy function to avoid buffer overruns.
            strcpy_s(destination, destinationSize, someString.c_str());
            }





            share|improve this answer



















            • 1





              It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

              – marsh
              Oct 12 '16 at 13:35






            • 1





              @marsh It is the caller's responsibility to check if he owns the returned pointer.

              – siwmas
              Jul 13 '18 at 15:36














            10












            10








            10







            In C++, the simplest thing to do is to just returna std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):



            std::string returnSomeString()
            {
            std::string someString;

            // some processing...

            return someString;
            }


            If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.



            // void SomeLegacyFunction(const char * psz)

            // .c_str() called on the returned string, to get the 'const char*'
            SomeLegacyFunction( returnSomeString().c_str() );


            If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new), and return a pointer to that:



            // NOTE: The caller owns the returned pointer, 
            // and must free the string using delete !!!
            const char* returnSomeString()
            {
            std::string someString;

            // some processing...

            // Dynamically allocate memory for the returned string
            char* ptr = new char[someString.c_str() + 1]; // +1 for terminating NUL

            // Copy source string in dynamically allocated string buffer
            strcpy(ptr, someString.c_str());

            // Return the pointer to the dynamically allocated buffer
            return ptr;
            }


            An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:



            void returnSomeString(char* destination, size_t destinationSize)
            {
            std::string someString;

            // some processing...

            // Copy string to destination buffer.
            // Use some safe string copy function to avoid buffer overruns.
            strcpy_s(destination, destinationSize, someString.c_str());
            }





            share|improve this answer













            In C++, the simplest thing to do is to just returna std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):



            std::string returnSomeString()
            {
            std::string someString;

            // some processing...

            return someString;
            }


            If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.



            // void SomeLegacyFunction(const char * psz)

            // .c_str() called on the returned string, to get the 'const char*'
            SomeLegacyFunction( returnSomeString().c_str() );


            If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new), and return a pointer to that:



            // NOTE: The caller owns the returned pointer, 
            // and must free the string using delete !!!
            const char* returnSomeString()
            {
            std::string someString;

            // some processing...

            // Dynamically allocate memory for the returned string
            char* ptr = new char[someString.c_str() + 1]; // +1 for terminating NUL

            // Copy source string in dynamically allocated string buffer
            strcpy(ptr, someString.c_str());

            // Return the pointer to the dynamically allocated buffer
            return ptr;
            }


            An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:



            void returnSomeString(char* destination, size_t destinationSize)
            {
            std::string someString;

            // some processing...

            // Copy string to destination buffer.
            // Use some safe string copy function to avoid buffer overruns.
            strcpy_s(destination, destinationSize, someString.c_str());
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 11 '14 at 16:26









            Mr.C64Mr.C64

            28.3k1062119




            28.3k1062119








            • 1





              It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

              – marsh
              Oct 12 '16 at 13:35






            • 1





              @marsh It is the caller's responsibility to check if he owns the returned pointer.

              – siwmas
              Jul 13 '18 at 15:36














            • 1





              It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

              – marsh
              Oct 12 '16 at 13:35






            • 1





              @marsh It is the caller's responsibility to check if he owns the returned pointer.

              – siwmas
              Jul 13 '18 at 15:36








            1




            1





            It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

            – marsh
            Oct 12 '16 at 13:35





            It is worth noting that the second example is probably not a very good idea. The caller is not going to expect that they have to delete that pointer and will most likely result in a memory leak.

            – marsh
            Oct 12 '16 at 13:35




            1




            1





            @marsh It is the caller's responsibility to check if he owns the returned pointer.

            – siwmas
            Jul 13 '18 at 15:36





            @marsh It is the caller's responsibility to check if he owns the returned pointer.

            – siwmas
            Jul 13 '18 at 15:36











            5














            As this question is flagged C, do this:



            #define _POSIX_C_SOURCE 200809L
            #include <string.h>

            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
            }


            Do not forget to free() what the function returned if of no use anymore.






            share|improve this answer


























            • I don't see the C flag, has it changed?

              – Yakk - Adam Nevraumont
              Mar 11 '14 at 18:53











            • @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

              – alk
              Mar 11 '14 at 19:37













            • Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

              – Tommaso Thea Cioni
              Jul 15 '18 at 17:24
















            5














            As this question is flagged C, do this:



            #define _POSIX_C_SOURCE 200809L
            #include <string.h>

            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
            }


            Do not forget to free() what the function returned if of no use anymore.






            share|improve this answer


























            • I don't see the C flag, has it changed?

              – Yakk - Adam Nevraumont
              Mar 11 '14 at 18:53











            • @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

              – alk
              Mar 11 '14 at 19:37













            • Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

              – Tommaso Thea Cioni
              Jul 15 '18 at 17:24














            5












            5








            5







            As this question is flagged C, do this:



            #define _POSIX_C_SOURCE 200809L
            #include <string.h>

            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
            }


            Do not forget to free() what the function returned if of no use anymore.






            share|improve this answer















            As this question is flagged C, do this:



            #define _POSIX_C_SOURCE 200809L
            #include <string.h>

            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
            }


            Do not forget to free() what the function returned if of no use anymore.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 11 '14 at 16:34

























            answered Mar 11 '14 at 16:17









            alkalk

            59k764177




            59k764177













            • I don't see the C flag, has it changed?

              – Yakk - Adam Nevraumont
              Mar 11 '14 at 18:53











            • @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

              – alk
              Mar 11 '14 at 19:37













            • Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

              – Tommaso Thea Cioni
              Jul 15 '18 at 17:24



















            • I don't see the C flag, has it changed?

              – Yakk - Adam Nevraumont
              Mar 11 '14 at 18:53











            • @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

              – alk
              Mar 11 '14 at 19:37













            • Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

              – Tommaso Thea Cioni
              Jul 15 '18 at 17:24

















            I don't see the C flag, has it changed?

            – Yakk - Adam Nevraumont
            Mar 11 '14 at 18:53





            I don't see the C flag, has it changed?

            – Yakk - Adam Nevraumont
            Mar 11 '14 at 18:53













            @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

            – alk
            Mar 11 '14 at 19:37







            @Yakk: The original posting (stackoverflow.com/revisions/22330250/1) carried the C tag.

            – alk
            Mar 11 '14 at 19:37















            Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

            – Tommaso Thea Cioni
            Jul 15 '18 at 17:24





            Thanks, I lost all my afternoon after a bug caused by something somewhat similar, but unfortunately more complicated. Anyway, thanks a lot.

            – Tommaso Thea Cioni
            Jul 15 '18 at 17:24











            3














            Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.



            But if what you want is a C-string, how about...



            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            char * new_string = new char[someString.length() + 1];

            std::strcpy(new:string, someString.c_str());

            return new_string;
            }


            But wait... that's almost exactly as returning a std::string, isn't it?



            std::string returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return new_string;
            }


            This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.



            Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).



            So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :



            void returnCharPtr(std::string & someString)
            {
            // some processing!.
            }


            Or, again, if you want C-Strings, you need to watch out for the length of your string:



            void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
            {
            // some processing!.
            }





            share|improve this answer





















            • 3





              Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

              – chris
              Mar 11 '14 at 16:13








            • 1





              You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

              – R. Martinho Fernandes
              Mar 11 '14 at 16:18











            • To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

              – Praetorian
              Mar 11 '14 at 16:19













            • Oh, my... I don't deserve to live D: I got it all backwards!

              – ArthurChamz
              Mar 11 '14 at 16:24











            • Thanks for all the corrections =)

              – ArthurChamz
              Mar 11 '14 at 16:27
















            3














            Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.



            But if what you want is a C-string, how about...



            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            char * new_string = new char[someString.length() + 1];

            std::strcpy(new:string, someString.c_str());

            return new_string;
            }


            But wait... that's almost exactly as returning a std::string, isn't it?



            std::string returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return new_string;
            }


            This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.



            Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).



            So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :



            void returnCharPtr(std::string & someString)
            {
            // some processing!.
            }


            Or, again, if you want C-Strings, you need to watch out for the length of your string:



            void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
            {
            // some processing!.
            }





            share|improve this answer





















            • 3





              Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

              – chris
              Mar 11 '14 at 16:13








            • 1





              You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

              – R. Martinho Fernandes
              Mar 11 '14 at 16:18











            • To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

              – Praetorian
              Mar 11 '14 at 16:19













            • Oh, my... I don't deserve to live D: I got it all backwards!

              – ArthurChamz
              Mar 11 '14 at 16:24











            • Thanks for all the corrections =)

              – ArthurChamz
              Mar 11 '14 at 16:27














            3












            3








            3







            Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.



            But if what you want is a C-string, how about...



            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            char * new_string = new char[someString.length() + 1];

            std::strcpy(new:string, someString.c_str());

            return new_string;
            }


            But wait... that's almost exactly as returning a std::string, isn't it?



            std::string returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return new_string;
            }


            This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.



            Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).



            So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :



            void returnCharPtr(std::string & someString)
            {
            // some processing!.
            }


            Or, again, if you want C-Strings, you need to watch out for the length of your string:



            void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
            {
            // some processing!.
            }





            share|improve this answer















            Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.



            But if what you want is a C-string, how about...



            const char * returnCharPtr()
            {
            std::string someString;

            // some processing!.

            char * new_string = new char[someString.length() + 1];

            std::strcpy(new:string, someString.c_str());

            return new_string;
            }


            But wait... that's almost exactly as returning a std::string, isn't it?



            std::string returnCharPtr()
            {
            std::string someString;

            // some processing!.

            return new_string;
            }


            This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.



            Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).



            So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :



            void returnCharPtr(std::string & someString)
            {
            // some processing!.
            }


            Or, again, if you want C-Strings, you need to watch out for the length of your string:



            void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
            {
            // some processing!.
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 14 '14 at 7:32









            jmac

            6,27312252




            6,27312252










            answered Mar 11 '14 at 16:07









            ArthurChamzArthurChamz

            1,664925




            1,664925








            • 3





              Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

              – chris
              Mar 11 '14 at 16:13








            • 1





              You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

              – R. Martinho Fernandes
              Mar 11 '14 at 16:18











            • To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

              – Praetorian
              Mar 11 '14 at 16:19













            • Oh, my... I don't deserve to live D: I got it all backwards!

              – ArthurChamz
              Mar 11 '14 at 16:24











            • Thanks for all the corrections =)

              – ArthurChamz
              Mar 11 '14 at 16:27














            • 3





              Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

              – chris
              Mar 11 '14 at 16:13








            • 1





              You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

              – R. Martinho Fernandes
              Mar 11 '14 at 16:18











            • To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

              – Praetorian
              Mar 11 '14 at 16:19













            • Oh, my... I don't deserve to live D: I got it all backwards!

              – ArthurChamz
              Mar 11 '14 at 16:24











            • Thanks for all the corrections =)

              – ArthurChamz
              Mar 11 '14 at 16:27








            3




            3





            Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

            – chris
            Mar 11 '14 at 16:13







            Don't return an rvalue reference. It has the same problem as an lvalue reference. (N)RVO takes care of expensive return copying even before C++11, and in C++11, the object will be moved out automatically if it can and (N)RVO doesn't work.

            – chris
            Mar 11 '14 at 16:13






            1




            1





            You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

            – R. Martinho Fernandes
            Mar 11 '14 at 16:18





            You just committed the same crime you accused the OP of! </joke> Rvalue references are still references, and returning one doesn't change the fact that it's still a reference to a local variable.

            – R. Martinho Fernandes
            Mar 11 '14 at 16:18













            To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

            – Praetorian
            Mar 11 '14 at 16:19







            To add to what chris said, the code where you return an rvalue reference won't even compile as written, you need to return move(new_string); (and then you get to deal with a dangling reference). And your C-string example doesn't make sense at all; the function is taking a pointer to const when the intent is to operate on the input string? Also, that signature assumes the caller knows the length of the result.

            – Praetorian
            Mar 11 '14 at 16:19















            Oh, my... I don't deserve to live D: I got it all backwards!

            – ArthurChamz
            Mar 11 '14 at 16:24





            Oh, my... I don't deserve to live D: I got it all backwards!

            – ArthurChamz
            Mar 11 '14 at 16:24













            Thanks for all the corrections =)

            – ArthurChamz
            Mar 11 '14 at 16:27





            Thanks for all the corrections =)

            – ArthurChamz
            Mar 11 '14 at 16:27











            1














            The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.



            Stay with std::string.






            share|improve this answer




























              1














              The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.



              Stay with std::string.






              share|improve this answer


























                1












                1








                1







                The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.



                Stay with std::string.






                share|improve this answer













                The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.



                Stay with std::string.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 11 '14 at 15:44







                user2033018






























                    1














                    Your options are:



                    Return std::string



                    Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.



                    Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
                    This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.



                    Choose the first one; return std::string.
                    It is by far the simplist and safest option.






                    share|improve this answer




























                      1














                      Your options are:



                      Return std::string



                      Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.



                      Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
                      This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.



                      Choose the first one; return std::string.
                      It is by far the simplist and safest option.






                      share|improve this answer


























                        1












                        1








                        1







                        Your options are:



                        Return std::string



                        Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.



                        Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
                        This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.



                        Choose the first one; return std::string.
                        It is by far the simplist and safest option.






                        share|improve this answer













                        Your options are:



                        Return std::string



                        Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.



                        Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
                        This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.



                        Choose the first one; return std::string.
                        It is by far the simplist and safest option.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Mar 11 '14 at 16:07









                        xen-0xen-0

                        664511




                        664511























                            1














                            The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.



                            Don't return .c_str() of string that could be destroyed before you use the returned char pointer.



                            Instead of...



                            const char* function()
                            {
                            std::string someString;
                            // some processing!
                            return someString.c_str();
                            }

                            //...

                            useCharPtr(function());


                            use



                            std::string function()
                            {
                            std::string someString;
                            // some processing!
                            return someString;
                            }

                            //...

                            useCharPtr(function().c_str());





                            share|improve this answer




























                              1














                              The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.



                              Don't return .c_str() of string that could be destroyed before you use the returned char pointer.



                              Instead of...



                              const char* function()
                              {
                              std::string someString;
                              // some processing!
                              return someString.c_str();
                              }

                              //...

                              useCharPtr(function());


                              use



                              std::string function()
                              {
                              std::string someString;
                              // some processing!
                              return someString;
                              }

                              //...

                              useCharPtr(function().c_str());





                              share|improve this answer


























                                1












                                1








                                1







                                The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.



                                Don't return .c_str() of string that could be destroyed before you use the returned char pointer.



                                Instead of...



                                const char* function()
                                {
                                std::string someString;
                                // some processing!
                                return someString.c_str();
                                }

                                //...

                                useCharPtr(function());


                                use



                                std::string function()
                                {
                                std::string someString;
                                // some processing!
                                return someString;
                                }

                                //...

                                useCharPtr(function().c_str());





                                share|improve this answer













                                The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.



                                Don't return .c_str() of string that could be destroyed before you use the returned char pointer.



                                Instead of...



                                const char* function()
                                {
                                std::string someString;
                                // some processing!
                                return someString.c_str();
                                }

                                //...

                                useCharPtr(function());


                                use



                                std::string function()
                                {
                                std::string someString;
                                // some processing!
                                return someString;
                                }

                                //...

                                useCharPtr(function().c_str());






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Mar 11 '14 at 16:08









                                milleniumbugmilleniumbug

                                12.7k33462




                                12.7k33462























                                    1














                                    You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)



                                    void returnCharPtr(char* someString)
                                    {
                                    // some processing!
                                    if(someString[0] == 'A')
                                    someString++;
                                    }





                                    share|improve this answer





















                                    • 1





                                      This assumes the caller knows how long the string is going to be, which is most often not the case.

                                      – Praetorian
                                      Mar 11 '14 at 16:13
















                                    1














                                    You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)



                                    void returnCharPtr(char* someString)
                                    {
                                    // some processing!
                                    if(someString[0] == 'A')
                                    someString++;
                                    }





                                    share|improve this answer





















                                    • 1





                                      This assumes the caller knows how long the string is going to be, which is most often not the case.

                                      – Praetorian
                                      Mar 11 '14 at 16:13














                                    1












                                    1








                                    1







                                    You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)



                                    void returnCharPtr(char* someString)
                                    {
                                    // some processing!
                                    if(someString[0] == 'A')
                                    someString++;
                                    }





                                    share|improve this answer















                                    You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)



                                    void returnCharPtr(char* someString)
                                    {
                                    // some processing!
                                    if(someString[0] == 'A')
                                    someString++;
                                    }






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Mar 11 '14 at 16:16

























                                    answered Mar 11 '14 at 15:45









                                    MrDukMrDuk

                                    4,31893879




                                    4,31893879








                                    • 1





                                      This assumes the caller knows how long the string is going to be, which is most often not the case.

                                      – Praetorian
                                      Mar 11 '14 at 16:13














                                    • 1





                                      This assumes the caller knows how long the string is going to be, which is most often not the case.

                                      – Praetorian
                                      Mar 11 '14 at 16:13








                                    1




                                    1





                                    This assumes the caller knows how long the string is going to be, which is most often not the case.

                                    – Praetorian
                                    Mar 11 '14 at 16:13





                                    This assumes the caller knows how long the string is going to be, which is most often not the case.

                                    – Praetorian
                                    Mar 11 '14 at 16:13











                                    1














                                    If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.



                                    char* returnCharPtr() 
                                    {
                                    std::string someString;

                                    // some processing!.

                                    char* cp = new char[someString.length()+1];
                                    strcpy(cp, someString.c_str());
                                    return cp;
                                    }





                                    share|improve this answer




























                                      1














                                      If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.



                                      char* returnCharPtr() 
                                      {
                                      std::string someString;

                                      // some processing!.

                                      char* cp = new char[someString.length()+1];
                                      strcpy(cp, someString.c_str());
                                      return cp;
                                      }





                                      share|improve this answer


























                                        1












                                        1








                                        1







                                        If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.



                                        char* returnCharPtr() 
                                        {
                                        std::string someString;

                                        // some processing!.

                                        char* cp = new char[someString.length()+1];
                                        strcpy(cp, someString.c_str());
                                        return cp;
                                        }





                                        share|improve this answer













                                        If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.



                                        char* returnCharPtr() 
                                        {
                                        std::string someString;

                                        // some processing!.

                                        char* cp = new char[someString.length()+1];
                                        strcpy(cp, someString.c_str());
                                        return cp;
                                        }






                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Mar 11 '14 at 16:22









                                        R SahuR Sahu

                                        168k1292191




                                        168k1292191























                                            1














                                            A solution which hasn't been evoked in the other answers.



                                            In case your method is a member of a class, like so:



                                            class A {
                                            public:
                                            const char *method();
                                            };


                                            And if the class instance will live beyond the usefulness of the pointer, you can do:



                                            class A {
                                            public:
                                            const char *method() {
                                            string ret = "abc";
                                            cache.push_back(std::move(ret));
                                            return cache.last().c_str();
                                            }
                                            private:
                                            vector<string> cache; //std::deque would be more appropriate but is less known
                                            }


                                            That way the pointers will be valid up till A's destruction.



                                            If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.






                                            share|improve this answer




























                                              1














                                              A solution which hasn't been evoked in the other answers.



                                              In case your method is a member of a class, like so:



                                              class A {
                                              public:
                                              const char *method();
                                              };


                                              And if the class instance will live beyond the usefulness of the pointer, you can do:



                                              class A {
                                              public:
                                              const char *method() {
                                              string ret = "abc";
                                              cache.push_back(std::move(ret));
                                              return cache.last().c_str();
                                              }
                                              private:
                                              vector<string> cache; //std::deque would be more appropriate but is less known
                                              }


                                              That way the pointers will be valid up till A's destruction.



                                              If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.






                                              share|improve this answer


























                                                1












                                                1








                                                1







                                                A solution which hasn't been evoked in the other answers.



                                                In case your method is a member of a class, like so:



                                                class A {
                                                public:
                                                const char *method();
                                                };


                                                And if the class instance will live beyond the usefulness of the pointer, you can do:



                                                class A {
                                                public:
                                                const char *method() {
                                                string ret = "abc";
                                                cache.push_back(std::move(ret));
                                                return cache.last().c_str();
                                                }
                                                private:
                                                vector<string> cache; //std::deque would be more appropriate but is less known
                                                }


                                                That way the pointers will be valid up till A's destruction.



                                                If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.






                                                share|improve this answer













                                                A solution which hasn't been evoked in the other answers.



                                                In case your method is a member of a class, like so:



                                                class A {
                                                public:
                                                const char *method();
                                                };


                                                And if the class instance will live beyond the usefulness of the pointer, you can do:



                                                class A {
                                                public:
                                                const char *method() {
                                                string ret = "abc";
                                                cache.push_back(std::move(ret));
                                                return cache.last().c_str();
                                                }
                                                private:
                                                vector<string> cache; //std::deque would be more appropriate but is less known
                                                }


                                                That way the pointers will be valid up till A's destruction.



                                                If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.







                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Jun 8 '16 at 13:42









                                                coyotte508coyotte508

                                                4,52142050




                                                4,52142050






























                                                    draft saved

                                                    draft discarded




















































                                                    Thanks for contributing an answer to Stack Overflow!


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid



                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.


                                                    To learn more, see our tips on writing great answers.




                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function () {
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f22330250%2fhow-to-return-a-stdstring-c-str%23new-answer', 'question_page');
                                                    }
                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    Popular posts from this blog

                                                    Contact image not getting when fetch all contact list from iPhone by CNContact

                                                    count number of partitions of a set with n elements into k subsets

                                                    A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks