为什么以下代码中的分段错误?

时间:2013-01-24 10:38:58

标签: c

我在维基百科上看到了这个

    int main(void)
 {

    char *s = "hello world";
    *s = 'H';

 }

当编译包含此代码的程序时,字符串“hello world”被放置在标记为只读的程序可执行文件的部分中;加载时,操作系统将其与其他字符串和常量数据放在只读的内存段中。执行时,变量s设置为指向字符串的位置,并尝试通过变量将H字符写入内存,从而导致分段错误**

我不知道为什么字符串被放在只读段中。请有人解释一下。

5 个答案:

答案 0 :(得分:3)

字符串文字存储在只读内存中,这就是它的工作原理。您的代码使用初始化的指针指向存储字符串文字的内存,因此您无法有效地修改该内存。

要在可修改的内存中获取字符串,请执行以下操作:

char s[] = "hello world";

然后你很好,因为现在你只是使用常量字符串来初始化一个非常量数组。

答案 1 :(得分:3)

之间存在很大差异:

char * s = "Hello world";

char s[] = "Hello world";

在第一种情况下,s是指向您无法更改的内容的指针。它存储在只读存储器中(通常在应用程序的代码部分中)。

在后一种情况下,您可以在读写内存(通常是普通RAM)中分配一个数组,您可以修改它。

答案 2 :(得分:2)

  • 当您执行:char *s = "hello world";时,s 指向代码部分中的内存的指针,所以你不能改变它。

  • 执行:char s[] = "Hello World";时,s 是一组字符堆栈上,您可以更改它。

如果您不希望在程序中更改字符串,最好执行:char const *s = ....;。然后,当您尝试更改字符串时,程序不会因分段错误而崩溃,会出现编译器错误(这要好得多)。

答案 3 :(得分:0)

首先要对指针有一个很好的理解,我会给你一个简短的演示:

首先让我们逐行分析您的代码。让我们从主要开始

char * s =“Some_string”;

首先,你要声明一个指向char变量的指针,现在* s是内存中的一个地址,如果你试图改变它的内存值,C会踢你,这是非法的,所以你最好声明一个字符数组,然后将s分配给其地址,然后更改s。

希望你得到它。有关进一步参考和详细了解,请参阅KN King:C编程现代方法

答案 4 :(得分:0)

根据语言定义,字符串文字必须以这样的方式存储,即它们的生命周期在程序的生命周期中延伸,并且它们在整个程序中是可见的。

根据 字符串的存储方式,这意味着直到实现;语言定义并不强制将字符串文字存储在只读内存中,并非所有实现都这样做。它只表示尝试修改字符串文字的内容会导致未定义的行为,这意味着实现可以随意执行任何操作。