5

Both these calls to get_string and get_string2 return objects which go out of scope when the function returns. Shouldn't the returned object be an address in memory which goes out of scope after the function returns? This is using Visual Studio 2008. Should this always work? Why?

#include <iostream>

enum myID { SMALL, MEDIUM, LARGE };

const char* get_string(myID id) {
   switch(id){
      case SMALL: return "small";
      case MEDIUM: return "medium";
      case LARGE: return "large";
      default: return "unknown";
   }
}

const char* get_string2(myID id) {
   char* s = 0;
   switch(id){
      case SMALL:  s = "small"; return s;
      case MEDIUM: s = "medium"; return s;
      case LARGE:  s = "large"; return s;
      default: return "unknown";
   }
}

int main() {
   std::cout << get_string(SMALL) << std::endl;
   std::cout << get_string2(SMALL) << std::endl;
   return 0;
}
1

2 Answers 2

12

String literals are the only literals that are lvalues and have static storage duration. So returning a pointer to the first element of a string literal is very safe. Compare

const char* f1()
{
      return "Hello"; // OK
} 

const char* f2()
{
      const char s[6] = "Hello";
      return s; // Undefined Behavior
} 


const char* f3()
{
      const char* s = "Hello";
      return s; //OK
} 

Judging from comments, this answer needs some elaboration. OK, see, a string literal is stored in the memory until the program has finished. In case 1 you return a pointer to it. The object pointer to is alive, so it's fine. In case 3, you take the address of the literal into a local variable s and return the latter by copy. The copy of the address still points to a valid memory, so it's fine. In the second case, however, we copy the string literal into a local array s which is destroyed upon function exit. Returning the address of a local variable is undefined behavior.

Further, if what you thought was undefined behavior were actually undefined then you shouldn't be surprised either because undefined behavior can mean

  • doesn't work
  • works sometimes
  • always works
  • does funny inexplicable stuff
  • anything

So if something works it doesn't mean it's OK. In this case it is, but not in the general case.

Sign up to request clarification or add additional context in comments.

7 Comments

So because it is a string literal it is not stored as a stack variable? It is stored in a global variable? Do you have a web link with details of this?
would you mind to explain a bit further on the undefined behavior case? I just like to know
Just a nit (because the effect is the same), but in f2, you don't copy anything (officially, at least). It's exactly as if you'd written char const s[6] = { 'H', 'e', 'l', 'l', '0', '\0' };.
@JamesKanze: You are of course right, since it is initialization, but I think it is easier to understand it this way. At least in this question.
now I think I need to go back again study the difference of an array and a pointer
|
4

This memory does not go out of the scope. These are string literals, they exist all time while the program runs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.