33

I know this is wrong:

char* getSomething() {  
    char szLocal[5];  
    /* put something in the char array somehow */  
    return szLocal;  
}  

...because szLocal can be destroyed sometime after the function returns.

But is this ok?

char* getSomethingElse() {  
    return "something else";  
}  
John Fitzpatrick
  • 4,207
  • 7
  • 48
  • 71
  • 3
    See [C String literals: Where do they go?](http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go). – Bertrand Marron Jan 29 '11 at 11:15
  • 8
    In the first example, szLocal is destroyed not "sometime after", but exactly at the very moment the function returns, so the returned pointer is already invalid. True, the data it points at will remain the same for "some time", but the function's stack frame is freed already, and the memory becomes available for use by anyone who needs to create some local variables or call another function. – Sergei Tachenov Jan 29 '11 at 11:21

3 Answers3

28

That is actually OK. The string literal is usually allocated in an immutable memory area that remains available for as long as your program is running.

See also the answers to when does c/c++ allocate string literals.

Community
  • 1
  • 1
Roman Starkov
  • 59,298
  • 38
  • 251
  • 324
  • I agree with romkyns. However, we don't know what system you're working on? There may be some out there that don't work like that. For your own peace of mind, you could try purposefully stamping over the memory where we are suggesting the string is NOT living. i.e. the stack. Get stuff on the stack by either declaring and assiging some more local variables, or call some other functions with a few parameters. Ideally, call another function with a few parameters that itself declares and assigns some local variables. – Dave Jan 29 '11 at 11:19
  • OMG this place is awesome. 10 useful replies in 10 minutes. Thanks all. (I'm on x64 windows using vs2010 btw.) – John Fitzpatrick Jan 29 '11 at 11:37
  • 7
    String literals are guaranteed to live for the span of the application. It might not be in read-only/immutable memory, but they're guaranteed to exist for the lifetime of the application, so returning a pointer to one is fine. – nos Jan 29 '11 at 11:49
7

It's ok in terms of allocation: the string literal is implicitly static. It's not ok to return a non-const pointer to a literal.

If you want to return a modifiable (non-const) string, declare it a static char[]. Or better, return a copy:

return strdup("something else");

Don't forget to free afterwards. strdup is non-ISO but available almost everywhere (except MSVC, I believe).

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • strdup not available on msvc ? are you sure ? – Mandrake Jan 29 '11 at 11:59
  • @Arabcoder: no, I'm not sure, and please correct me if I'm wrong. I don't do MSVC. – Fred Foo Jan 29 '11 at 12:00
  • 1
    Good point about const. Wouldn't a (good) compiler catch this though - an attempt to cast const char to non-const char? – Roman Starkov Jan 29 '11 at 12:05
  • 1
    @romkyns: GCC 4.5 doesn't even complain with `-Wall`: as Jens Gustedt points out below nominolo's answer, a literal isn't `const`. (G++ complains, but still compiles the module, and then we're out of the C world.) – Fred Foo Jan 29 '11 at 12:12
  • 1
    I see. I suppose if I were to be pedantic then returning a literal as non-const is not an outright error then. Still, very C-like to let you shoot yourself in the foot by making literals non-const. – Roman Starkov Jan 29 '11 at 13:10
5

The type of a string literal is const char * (see comments below) static char[], but immutable. A string literal represents a pointer to statically allocated memory. Therefore:

  1. It is perfectly fine, to return a such a pointer.

  2. Your function return type must should be compatible with const char*, i.e., return type char * will give you at least a warning may give you trouble later on.

  3. If you function may return both a literal or malloced string you have to be very careful about memory management. freeing a string literal probably will segfault.

nominolo
  • 5,085
  • 2
  • 25
  • 31
  • 2
    Actually, the type is `static const char[]`, i.e. closer to `const char *const`. You can't increment or decrement a literal. – Fred Foo Jan 29 '11 at 11:19
  • 3
    @larsman: No, unfortunately for historical reasons its type is not `const` qualified. But you don't have the right to change it :(( So it is certainly a good idea to declare the return value `const` but the language doesn't enforce this. – Jens Gustedt Jan 29 '11 at 11:28
  • @larsman, @Jens: Thanks, I stand corrected. I should have checked before submitting. – nominolo Jan 31 '11 at 22:50