【问题标题】:Replacing a character using pointer in ANSI C在 ANSI C 中使用指针替换字符
【发布时间】:2013-11-10 23:46:16
【问题描述】:

我正在使用 ubuntu 12.04lts 和 gcc(Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3。我可以在第一个程序中替换一个字符,但是为什么我不能在第二个程序中得到输出,即使它编译成功了?我得到分段错误。谁能解释原因?

  #include<stdio.h>
  int main(void)
  {
  char word[] = "Bhilip";
  char *cp = word ;
  puts(word);
  cp[1] = 'T';  // allowed??
  puts(word);
  return 0;
  }



  #include<stdio.h>
  int main(void)
  {
    char * p1 = "Bhilip";
    p1[0] = 'T';    //allowed?
    printf("\nThilip");
    printf(" %s \n\n", "Thilip");
    return 0 ;
  }

【问题讨论】:

    标签: c string pointers


    【解决方案1】:

    根据ISO C11 6.4.5 String literals /6(尽管这种行为在标准的早期迭代中已经存在了很长一段时间):

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

    这意味着如果您希望明确定义行为,则不允许修改字符串文字的内容。它可能适用于某些实现,但不能保证。在一些实现中,字符串文字被放置在标记为只读的内存中,以便尝试修改它会导致引发错误。在其他(例如嵌入式系统)中,它可能被放置在实际只读内存(ROM)中,这样即使它没有故障,内存也保持不变。

    这背后的一个可能原因是它使编译器能够将字符串文字折叠在一起以提高效率。例如,如果你的代码有definedundefined这两个字符串,它们在内存中可能存在如下:

            +---+---+---+---+---+---+---+---+---+----+
    0x1234: | u | n | d | e | f | i | n | e | d | \0 |
            +---+---+---+---+---+---+---+---+---+----+
    

    undefined的地址为0x1234defined的地址为0x1236

    这个起作用的原因:

    char word[] = "Bhilip";
    

    是因为它创建了一个可以合法修改的字符数组,有效地:

    • 创建可修改数组;那么
    • 将单个字符复制到其中。

    换句话说,它在功能上等同于:

    char word[7];             // modifiable
    strcpy (word, "Bhilip");  // initialise
    

    【讨论】:

      【解决方案2】:
      char * p1 = "Bhilip";
      

      声明一个指向字符串文字的指针。这可能保存在只读存储器中,因此无法修改。

      p1[0] = 'T';
      

      尝试修改字符串文字中的第一个字符。这会导致未定义的行为,包括可能的段错误。

      如果你想要一个可写的字符串,你可以声明一个堆栈缓冲区并用字符串字面量初始化它

      char p1[] = "Bhilip";
      p1[0] = 'T'; // now allowed
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多