代码之家  ›  专栏  ›  技术社区  ›  Kraken

为什么在这个C程序中写入字符串文字会出错?

c
  •  5
  • Kraken  · 技术社区  · 15 年前
    #include<stdio.h>
    
    void main()
    {
        char *p="nyks";
    
        p[2]='n';
    
        printf("%s",p);
    }
    

    它与一个 分段故障 . 有人能解释为什么吗?

    6 回复  |  直到 11 年前
        1
  •  7
  •   linuxuser27    15 年前

    标准规定定义文字字符串 const . 你不能改变它。

    编译器将文本放在只读内存段中。您可以输出程序集并观察它。如果您使用的是GCC,那么它是通过-s标志完成的。它将把字符串放在.rodata节中。

        2
  •  15
  •   Matthew Flaschen    15 年前

    试图覆盖字符串文字是未定义的行为。C99§6.4.5/6:

    如果程序试图修改

    附录J.2(未定义行为)对此进行了重申。

    如果您这样做:

    char p[] = "nyks";
    

    可以分配和初始化自动(堆栈)字符数组。在这种情况下,完全可以修改元素。

        3
  •  3
  •   Donal Fellows    15 年前

    其他答案是从标准的角度来看的,但这里有 它崩溃了。

    编译器通常将程序文本(尤其是字符串)放在只读内存中。操作系统将内存标记为只读,因此任何对其进行写入的尝试都将被捕获,在您的平台上,这就是分段错误所指示的;尝试在某些内存上执行不允许的操作。与坏内存使用相关的另一种崩溃是总线错误,它通常表示未对齐的内存访问或对根本没有映射的页的写入。对于C代码来说,这种差异几乎完全是学术上的(其他一些语言实现使用这些错误来帮助它们管理内存)。

    请注意,将写入限制为只读与语言的官方语义无关。而你可能有一个 char* 指着它,你还是写不出来。始终将程序文本视为指向常量内存,这样就不会出错(默认情况下,它们不是,因为需要支持与旧程序的兼容性)。

        4
  •  1
  •   James Curran    15 年前

    这意味着(本质上):

     #include<stdio.h>  
     const char privatestring[5] = {"nyks"};
    
     void main()  
     {  
        char *p = const_cast<char*>(privatestring); 
        p[2]='n';        
    
        printf("%s",p);        
     }        
    

    允许编译器 privatestring 你只有读权限的地方。它执行const\u强制转换,以向后兼容在const关键字之前编写的程序。

        5
  •  1
  •   kapil effeffe    11 年前

    该值是无法修改的字符串文字,因为文字存储在只读内存中,请尝试p[]取而代之的是分割错误通常是由于指针的错误使用造成的。

        6
  •  0
  •   usta    15 年前

    字符串文字不可修改。。。 写作能力 char *p="nyks"; 实际上是C中的一个类型系统漏洞。