Thread: Returning const char*/ std::string.c_str()

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    127

    Returning const char*/ std::string.c_str()

    Hi,

    I have a function in a program that's something like the following. When I try to output what it returns, however, it doesn't print anything on the screen. The following isn't exactly what I'm using, but it gets the point across.

    Code:
    const char* getcolor(bool top)
    {
        stringstream color_convert;
        string string1;
    
        if (top == 1)
            color_convert << 160;
        else
            color_convert << 200;
    
        string1 = color_convert.str();
        return string1.c_str();
    }
    Alternately, if I replace the contents of the function with:

    Code:
    const char* c_string1 = "160";
    return c_string1;
    then it will return something that I can print out. Does anyone know why this is? I'm guessing it's something to do with pointers- like in the first function, the pointer to the string is empty after it's returned or something? It's weird though because both functions use pointers to stuff. I don't see why one should be empty and the other not.

    Thanks.

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    It's because you can't return a pointer pointing to part of a local variable. c_str() returns a string that is owned by your string1 object. This object gets deleted at the end of the function, and so does the return value of c_str().

    By contrast, you can return a pointer to a string literal, because string literals are stored in the same spot as global variables.

    Also the other hand something like this is not allowed, for the same reason, though it might occationally work anyway:
    Code:
    const char c_string1[] = "160";
    return c_string2;
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Is there a reason you don't just return a string?

    I ask because I find a lot of people convert to C style strings because they are unaware that the C++ string works in their situation as well.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Quote Originally Posted by Daved View Post
    Is there a reason you don't just return a string?

    I ask because I find a lot of people convert to C style strings because they are unaware that the C++ string works in their situation as well.
    I'm returning a c string because basically, I'm writing a mod for the game Half-Life. The only way you can print messages to the screen in Half-Life is via c_strings (Half-Life is written in C++ but it's based on the Quake 1 engine which is C). You have to use functions that are part of the Half-Life code to do this.

    I was wondering something though. The reason I ask this question is because my mod basically uses a class that outputs a load of stuff to a stringstream object. I also have some interface classes as part of my project. One of these just outputs the stringstream stuff to cout. Another outputs stuff via Half-Life. This one has some make_cstring_msg() member functions that convert the stuff in the stringstream to c_strings. Would I be better off just returning strings and then converting these to c_strings in the Half-Life code itself? By "Half-Life code itself" I mean basically you have to have this file called dll.cpp, and that's what interfaces with Half-Life. Hope that makes sense.

    Thanks.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You cannot even return a string in C (unless it's a char*, but then we have to be talking about malloc and who is responsible for freeing it). So, are you sure you need to RETURN a string, not copy it into some buffer?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Quote Originally Posted by Elysia View Post
    You cannot even return a string in C (unless it's a char*, but then we have to be talking about malloc and who is responsible for freeing it). So, are you sure you need to RETURN a string, not copy it into some buffer?
    Well to be honest, I don't know. Right now I do it via something like the following, which is one of the "make c string" functions I mentioned.

    Code:
    const char *get_th_choice_cstr()    { return choice_strings[th_choice-1].c_str(); }
    Presumably this is the wrong way to do it, and I'd be better off by having get_th_choice_cstr() declared as having an argument that's a pointer to a c string, right? So...

    Code:
    void get_th_choice_cstr(char *cstring1)    { strcpy(cstring1, choice_strings[th_choice-1].c_str()); }
    Would something like that make sense?

    Thanks for your help.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, the last one is the usual way to pass or return a string in C.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The first one shouldn't be wrong either, because now choice_strings is not a local variable.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Quote Originally Posted by anon View Post
    The first one shouldn't be wrong either, because now choice_strings is not a local variable.
    Yeah, I've been using that for a while and it seems to work. Still, is it better to do it the second way? Or doesn't it really matter? I have occasionally noticed the text screwing up in the game- bits of old messages being added onto the end of new ones etc. But I dunno if that's to do with this or just the game itself.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The second one is prone to buffer overruns. I guess that's what's behind what you are seeing.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Drawing Program
    By Max_Payne in forum C++ Programming
    Replies: 21
    Last Post: 12-21-2007, 05:34 PM
  2. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  3. "error: incomplete type is not allowed"
    By Fahrenheit in forum C++ Programming
    Replies: 9
    Last Post: 05-10-2005, 09:52 PM
  4. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM
  5. vector<>
    By teval in forum C++ Programming
    Replies: 11
    Last Post: 08-18-2003, 03:27 PM