【问题标题】:Why does this small C program crash?为什么这个小 C 程序会崩溃?
【发布时间】:2012-01-09 04:57:44
【问题描述】:

程序是:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char *a="abc",*ptr;
    ptr=a;
    ptr++;
    *ptr='k';
    printf("%c",*ptr);
    return 0;
}

问题出在

*ptr='k';  

行,当我删除它时,程序正常工作。但我无法弄清楚原因。

【问题讨论】:

  • 这个问题可以找到很好的解释here

标签: c crash


【解决方案1】:

问题是因为您试图更改字符串文字"abc"

char *a="abc",*ptr;
ptr=a;                  // ptr points to the 'a'.
ptr++;                  // now it points to the 'b'.
*ptr='k';               // now you try to change the 'b' to a 'k'.

这是未定义的行为。该标准明确规定,您不得按照 C99 的 6.4.5 String literals 部分更改字符串文字:

如果这些数组的元素具有适当的值,则未指定这些数组是否不同。如果程序尝试修改这样的数组,则行为未定义。

如果你替换它工作:

char *a="abc",*ptr;

与:

char a[]="abc",*ptr;

因为这会将字符串文字复制到可以安全修改的地方。

【讨论】:

    【解决方案2】:

    因为“abc”是一个常量字符串文字。然后你将ptr 指向它并尝试修改它,这是未定义的行为。通常,字符串文字被放在一个内存部分中,该部分被映射为只读 - 因此存在访问冲突。

    另请参阅此问题:String literals: Where do they go?

    【讨论】:

      【解决方案3】:

      原因是您的字符串"abc" 位于内存的只读区域中。它被链接器放在那里。你尝试在你的程序中改变它,所有的赌注都被取消了。

      【讨论】:

      • 更正:它在内存中可能是也可能不是只读的。完全允许它运行完成并打印出修改后的字符串。另一种可能性是它将修改另一个具有相同值的字符串文字。例如:int main() { char *s="abc"; s[1] = 'd'; printf("abc"); } 可能会打印出adc
      • 在OP的情况下,这绝对是因为只读内存。但是,真的,我已经看到你之前(在 PlayStation1 上)指出的内容了。如果我们打算改变其中的一个,我们必须故意让我们的字符串不同。 (欢乐时光。)
      【解决方案4】:

      这个:

      char *a="abc";
      

      真的是:

      const char *a="abc";
      

      你不能修改ptr,它指向与a相同的地址。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        • 2023-03-11
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多