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

给你一囗甜甜゛ 提交于 2019-12-04 02:35:52
Seth Carnegie

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.

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.

They are different. a points to a string literal that you cannot change. However, b is an array of characters that is initialized with the given string. Assuming the const were removed, then you can change the contents of b.

Yes they are different.

It is true that the string literals themselves ("hello" and "goodbye") are immutable. However, when you are accessing b, you are not accessing your original "goodbye". The code that you used declared a completely independent array b, which is only initialized with a string literal "goodbye". Your 'b' is totally independent from the original string literal "goodbye". Your b is a copy of that string literal. The only reason your 'b' is immutable is the const you explicitly included in its declaration. Remove that const and your b will become perfectly mutable, as any ordinary array is.

As for your 'a', it is a pointer that points directly to the original string literal "hello". It is, of course, immutable.

Both options are immutable, but not because they're created from a string literal. They're immutable because of the const keyword in the variable declarations.

You could also write char c[] = "string_c"; and you would create a mutable copy (named c) of the literal string_c.

In your example about removing the constness of b, that may appear to work in some circumstances, but it's still illegal as far as the standard is concerned. Only objects that are truly non-const may be mutated.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!