10

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?

4

5 回答 5

18

第一个创建一个指向字符串字面量的指针,该字面"hello"量可能存储在程序可执行映像中的不可写内存中。即使不是,您也不能修改该数组的内容。

第二个创建一个自动数组1(在堆栈上(通常,但这是实现定义的))并用 string 初始化它"goodbye"。它相当于

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

因此,虽然"goodbye"它是不可变的,因为它是一个char const[8]存储在不可写内存中的字符串文字,但该数组b是一个自动1数组,它是不可变的,因为您对其进行了标记const,但是您可以const从变量声明中删除 以使数组的内容可变. 您只是用数组的内容初始化数组的内容"goodbye"

您不能修改其中任何一个,因为它们都是const char[],但第二个可以更改为char[]可变,而第一个不能。

有关更多信息,请参阅此答案:https ://stackoverflow.com/a/9106798/726361


1正如 R. Martinho Fernandes 在评论中指出的那样,T x[] = ...如果它在命名空间范围内,语法也可以创建一个静态数组(不是自动的,而是静态的(通常在可执行映像中,但这是实现定义的)),并且它只是一个自动的否则数组。

于 2012-02-24T19:28:34.847 回答
6

字符串文字的类型为char const[N]; 当然,这种类型的名称可能会衰减为char const*.

现在:

  1. 数组可以char由字符串文字(8.5.2/1)初始化,并且由于您不能以其他方式复制或分配数组,因此该初始化实现了复制。您可以随意使用新的可变数组。

    char str[6] = "hello";
    
  2. 相反,在初始化指针时,您将获得一个指针,该指针是字符串文字的不可变数组类型衰减的结果。

    char const* str = "hello";
    

    这里没有新数组。只需将指针复制到现有的不可变数据即可。

于 2012-02-24T19:35:01.790 回答
0

它们不一样。 a指向您无法更改的字符串文字。但是,b是一个用给定字符串初始化的字符数组。假设const被删除,那么您可以更改b.

于 2012-02-24T19:28:39.240 回答
0

是的,它们是不同的。

确实,字符串文字本身 ("hello""goodbye") 是不可变的。但是,当您访问 时b,您并没有访问您的原始"goodbye". 您使用的代码声明了一个完全独立的数组b,它只使用字符串文字进行初始化"goodbye"。您的 'b' 完全独立于原始字符串字面量"goodbye"。您b是该字符串文字的副本。您的“b”不可变的唯一原因是const您明确包含在其声明中。删除它const,您b将变得完全可变,就像任何普通数组一样。

至于你的'a',它是一个直接指向原始字符串字面量的指针"hello"。当然,它是不可变的。

于 2012-02-24T19:40:10.700 回答
0

这两个选项都是不可变的,但不是因为它们是从字符串文字创建的。const由于变量声明中的关键字,它们是不可变的。

您也可以编写char c[] = "string_c";并创建文本的可变副本(名为cstring_c

在您关于删除 constness 的示例中b,这在某些情况下似乎可行,但就标准而言,它仍然是非法的。只有真正非常量的对象才能被变异。

于 2012-02-24T19:44:10.680 回答