1

可能重复:
char *str=“STRING”和 char str[]=“STRING”之间的区别?

我写了以下代码:

int main()
{
    char *str = "hello";
    str[0] = 'H';
    printf("%s\n", str);
}

这给了我一个分段错误,我不明白为什么。

str不是。pointer to char_ const char即使是这种情况,它也不应该给出如下程序的编译错误:

int main()
{
    const char *str = "hello";
    str[0] = 'H';
    printf("%s\n", str);    
}

它给出了一个错误:assignment of read-only location *str

编辑

如果我的代码将指针指向只读位置,我不应该得到编译错误吗?

4

6 回答 6

5

您分配一个指向常量字符串的指针(它作为文本的一部分出现,因此不是可写内存)。

修复char str[] = "hello";此问题将在堆栈上创建常量字符串的 ar/w 副本。

你所做的是一个完全有效的指针分配。编译器不知道的是,在标准系统中,常量字符串被放置在只读内存中。在嵌入式(或其他奇怪的)系统上,这可能会有所不同。

根据您的系统,您可以附带一个mprotect并将指针目标上的 VM 标志更改为可写。所以编译器允许这个代码,但你的操作系统不允许。

于 2012-10-06T17:11:10.717 回答
2

当您char *使用文字字符串初始化 a 时,您不应该尝试修改它的内容:该变量指向不属于您的内存。

可以使用:

char str[] = "hello";
str[0] = 'H';

使用此代码,您已经声明了一个使用文字字符串内容的副本初始化的数组,现在您可以修改该数组。

于 2012-10-06T17:11:44.597 回答
0

您的代码在运行时具有未定义的行为。您正在尝试写入不允许的文字字符串。此类写入可能会触发错误或具有未定义的行为。您的特定 C 编译器str指向只读内存,尝试写入该内存会导致分段错误。即使不是const,仍然不允许写入。

于 2012-10-06T17:12:03.463 回答
0
char *str = "hello";

当您str按上述方式声明时,不能保证它将存储哪一部分内存。str 可能是只读的,具体取决于实现。所以试图改变它会导致分段错误。

为了避免分段错误,改为声明str为字符数组。

于 2012-10-06T17:12:20.743 回答
0
char *str = "hello";

这里的字符串 hello 是一个文字。字符串文字总是存储在只读存储器中。这就是您在尝试更改只读内存中的值时遇到分段错误的原因。

于 2012-10-06T17:13:09.627 回答
0

将 str 声明为 char* 会为指针保留内存,但不会为字符串保留内存。编译器可以将“hello”的内存放在他喜欢的任何地方。您不能保证 str[i] 是可写的,这就是为什么在某些编译器中这会导致段错误。

如果要确保字符串在可写内存中,则必须使用 alloc() 分配内存,或者可以使用

char str[] = "hello";
于 2012-10-06T17:21:53.170 回答