Well for starters,
char* foo = "bar";
technically isn't legal, even though many compilers allow it (they allow it only to be compatible with legacy code. You should never do that in new code). string literals are constant so you'd have to do
const char* foo = "bar";
.
That said.... it has to do with memory management.
a pointer just points to memory that exists somewhere else. When you do this:
What's happening is the compiler keeps a constant string literal in the program somewhere (think: in the exe itself), and you create a variable named foo that points to that memory.
Conversely, using a char array does something quite different:
Instead of just pointing to existing memory, this allocates a new block of memory (20 chars big) and copies the "bar" string to that block of memory.
Now since this is actual modifiable memory and not merely pointing to strings that exist elsewhere, we can mess with the string data:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
char foo[20] = "bar";
cout << foo; // prints "bar"
foo[0] = 'f'; // OK to modify foo
cout << foo; // prints "far"
foo[2] = 'b';
cout << foo; // prints "fab"
strcat(foo,"ulous"); // append "ulous" to foo
cout << foo; // prints "fabulous"
|
None of that will work if you're pointing to a constant string literal like you would if you're using a
const char*
Let's take another example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
// assuming this works (even though it shouldn't!)
char* a = "test";
char* b = "test";
/* at this point, a and b both point to some memory in the exe that holds the string "test"
now rather than repeat "test" in the exe multiple times, the compiler will probably just make
a and b point to the same block of memory.
Similar to if you did this:
char memory[20] = "test";
char* a = memory;
char* b = memory;
*/
//also assuming this will work (even though it shouldn't):
a[0] = 'b';
cout << a; // we would expect this to print "best" (even though it might not)
cout << b; // but what about this?
|
We didn't change 'b' in that code, so you'd think it would print "test"... but it might not. If a and b indeed point to the same memory, and we modified that memory through a, then printing b is the same as printing a, in which case we'd get "best" instead of "test".
So basically:
- pointers just point to data that exists elsewhere
- char arrays actually hold the data themselves, they don't reference external memory
The string class is basically the exact same thing as a char array, only easier and safer to use since it can resize the buffer as needed (so you don't have to worry about overflowing string data past the end of what you allocated).
EDIT: doh I'm way too slow