更改 c 字符串中的一个字符

标签 c arrays

我试图理解为什么以下代码是非法的:

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/

相关文章:

c++ - 如何仅在文件存在时使用追加模式打开文件

c - C 编程中 "&"%f", &variableName);"中的 "scanf("是什么?

c - 两种形式的C赋值有什么区别

c - int main(int carg, const char **varg) {

javascript:如何按年龄对员工对象数组进行排序

c++ - 使用多个线程进行 GL 调用是否安全?

c - 缓冲区大小有限的缓冲区溢出攻击

java - 基于多个输入使用 hamcrest 和 lambdaj 比较对象

c++ - 如何从 vector 或数组中选择最常见的数字?(TOP5 toplist) C++

javascript - 动态Javascript数组.length