views:

222

answers:

2

So, I'm wanting to get a better grasp on how string literals in C++ work. I'm mostly concerned with situations where you're assigning the address of a string literal to a pointer, and passing it around. For example:

char* advice = "Don't stick your hands in the toaster.";

Now lets say I just pass this string around by copying pointers for the duration of the program. Sure, it's probably not a good idea, but I'm curious what would actually be going on behind the scenes.

For another example, let's say we make a function that returns a string literal:

char* foo()
{
    // function does does stuff
    return "Yikes!"; // somebody's feeble attempt at an error message
}

Now lets say this function is called very often, and the string literal is only used about half the time it's called:

// situation #1: it's just randomly called without heed to the return value
foo(); 

// situation #2: the returned string is kept and used for who knows how long
char* retVal = foo();

In the first situation, what's actually happening? Is the string just created but not used, and never deallocated?

In the second situation, is the string going to be maintained as long as the user finds need for it? What happens when it isn't needed anymore... will that memory be freed up then (assuming nothing points to that space anymore)?

Don't get me wrong, I'm not planning on using string literals like this. I'm planning on using a container to keep my strings in check (probably std::string). I'm mostly just wanting to know if these situations could cause problems either for memory management or corrupted data.

+16  A: 

String-literals have the type const char[N] (where N is the length + 1) and are statically allocated. You need not worry about memory issues; if a string is used in your program it is all handled for you, and resides somewhere in program memory (usually read-only).

That is, these are "the same":

static const char str[] = "a string";
"a string"

When you point to a string literal, you are pointing to the first character at the array. In fact, because the type is const char[], it's only safe to point to it via const char*. The conversion from string literal to char* is deprecated, and unsafe.

// the "same"
static const char str[] = "a string";
const char* strPtr = str; // decays

const char* s1 = "a string";
char* s2 = "a string"; // allowed, implicit const_cast

*s1 = 'A'; // not allowed, it's const
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior)
GMan
"The conversion from string literal to char* is deprecated, and unsafe." Yeah. Needs -fwritable-strings if you did that somewhere. Anyway, DON'T DO THAT.
Joshua
Yeah, thanks for explaining the const aspect in detail. I was aware that they were constant, but I figured I'd leave the explanation to someone who understood them better than I. :)
DoctorT
You've said it all, far as I can tell.
John Dibling
D.Shawley
+1  A: 

Firstly, declare the return value of foo as const, because string literals are constants that can't be changed without causing the dreaded "undefined behaviour". This will then force any pointers which use the return value of foo to also be declared as const, and potentially limiting the damage which can be (usually unintentionally) done. String literals are stored in the 'text' area of a binary executable - they're not created as such at run time.

James Morris