问题描述
我试图了解以下代码为何非法:
I am trying to understand why the following code is illegal:
int main ()
{
char *c = "hello";
c[3] = 'g'; // segmentation fault here
return 0;
}
编译器遇到char *c = "hello";
时会做什么?
What is the compiler doing when it encounters char *c = "hello";
?
按照我的理解,它是char的自动数组,而c
是第一个char的指针.如果是这样,c[3]
就像*(c + 3)
一样,我应该可以进行分配.
The way I understand it, its an automatic array of char, and c
is a pointer to the first char. If so, c[3]
is like *(c + 3)
and I should be able to make the assignment.
只是试图了解编译器的工作方式.
Just trying to understand the way the compiler works.
推荐答案
字符串常量是不可变的.即使将它们分配给char *
,也无法更改它们(因此,将它们分配给const char *
,这样就不会忘记).
String constants are immutable. You cannot change them, even if you assign them to a char *
(so assign them to a const char *
so you don't forget).
要更详细些,您的代码大致等同于:
To go into some more detail, your code is roughly equivalent to:
int main() {
static const char ___internal_string[] = "hello";
char *c = (char *)___internal_string;
c[3] = 'g';
return 0;
}
此___internal_string
通常分配给只读数据段-任何在此更改数据的尝试都将导致崩溃(严格来说,也可能发生其他结果-这是未定义行为"的一个示例) .但是,由于历史原因,编译器允许您分配给char *
,给您一种错误的印象,您可以对其进行修改.
This ___internal_string
is often allocated to a read-only data segment - any attempt to change the data there results in a crash (strictly speaking, other results can happen as well - this is an example of 'undefined behavior'). Due to historical reasons, however, the compiler lets you assign to a char *
, giving you the false impression that you can modify it.
请注意,如果执行此操作,它将起作用:
Note that if you did this, it would work:
char c[] = "hello";
c[3] = 'g'; // ok
这是因为我们正在初始化一个非常量字符数组.尽管语法看起来很相似,但是编译器对它的处理方式有所不同.
This is because we're initializing a non-const character array. Although the syntax looks similar, it is treated differently by the compiler.
这篇关于更改一个c字符串中的一个字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!