我试图理解为什么以下代码是非法的:
int main ()
{
char *c = "hello";
c[3] = 'g'; // segmentation fault here
return 0;
}
编译器在遇到char *c = "hello";
时在做什么?
按照我的理解,它是一个自动的char数组,c
是指向第一个char的指针。如果是这样,c[3]
就像 *(c + 3)
并且我应该能够进行分配。
只是想了解编译器的工作方式。
最佳答案
字符串常量是不可变的。您无法更改它们,即使您将它们分配给 char *
(因此请将它们分配给 const char *
,这样您就不会忘记)。
为了更详细一点,您的代码大致相当于:
int main() {
static const char ___internal_string[] = "hello";
char *c = (char *)___internal_string;
c[3] = 'g';
return 0;
}
这个 __internal_string
通常分配给一个只读数据段 - 任何更改那里数据的尝试都会导致崩溃(严格来说,其他结果也可能发生 - 这是一个例子'未定义的行为')。然而,由于历史原因,编译器允许您分配给 char *
,给您一种可以修改它的错误印象。
请注意,如果您这样做,它会起作用:
char c[] = "hello";
c[3] = 'g'; // ok
这是因为我们正在初始化一个非常量字符数组。尽管语法看起来相似,但编译器对其进行了不同的处理。
关于更改 c 字符串中的一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7547821/