Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C-String array initialization - is this mutable? [duplicate]

Tags:

c++

c-strings

Possible Duplicate:
Modifying C string constants?
Pointer to const char vs char array vs std::string

I know I'm probably beating the dead horse with this question, but I'm a little confused and I haven't managed to find an exact answer on SO or google (that I'm confident is right - there's just too much information on C-strings to sift through). Also, I've tagged it C++ because that's what I'm interested in, even though we're talking about C-style strings specifically.

In this situation:

char const a*  = "hello";
char const b[] = "goodbye";

I would have thought that "hello" and "goodbye" were both immutable strings because they come from string-literals that should decay to a char const*.

I've seen that in this particular case though, changing "hello" would be undefined while changing "goodbye" would be fine, assuming you stripped the constness from the b-array.

I assume that the string is mutable in the case of b due to the fact that its stored in a user-defined array.

Are hello and goodbye different in this case? Is goodbye not a string-literal for some reason given this example. Also, if goodbye isn't a string-literal, can I assume it isn't held in global memory, and the only reference to it after compile time is that which is left in the user-array cells?

like image 306
John Humphreys Avatar asked Feb 24 '12 19:02

John Humphreys


2 Answers

The first one creates a pointer that points to the string literal "hello", which is probably stored in non-writable memory in the executable image of the program. Even if it isn't, you are not allowed to modify the contents of that array.

The second one creates an automatic array1 (on the stack (usually, but that is implementation-defined)) and initialises it with the string "goodbye". It is equivalent to

char const b[] = {'g', 'o', 'o', 'd', 'b', 'y', 'e', 0};

So while "goodbye" is immutable because it is a string literal which is char const[8] and stored in non-writable memory, the array b is an automatic1 array that is immutable because you marked it const, but you could remove the const from the variable declaration to make the array's contents mutable. You are only initialising the contents of the array with the contents of the array "goodbye".

You are not allowed to modify either of them because they are both const char[], but the second one could be changed to char[] to be mutable, while the first one could not.

See this answer for more info: https://stackoverflow.com/a/9106798/726361


1 As R. Martinho Fernandes pointed out in the comments, the syntax T x[] = ... could also create a static array (not automatic but static (in the executable image usually, but that's implementation defined)) if it is at namespace scope, and it's only an automatic array otherwise.

like image 108
Seth Carnegie Avatar answered Oct 24 '22 23:10

Seth Carnegie


A string literal has type char const[N]; of course a name of this type may decay to a char const*.

Now:

  1. A char array may be initialised by a string literal (8.5.2/1), and since you cannot otherwise copy or assign arrays, it follows that this initialisation implements a copy. You're free to do with the new, mutable array whatever you like.

    char str[6] = "hello";
    
  2. Conversely, when initialising a pointer, you're obtaining a pointer that's the result of the string literal's immutable array type decaying.

    char const* str = "hello";
    

    There is no new array here. Just copying a pointer to the existing, immutable data.

like image 41
Lightness Races in Orbit Avatar answered Oct 25 '22 00:10

Lightness Races in Orbit