【问题标题】:Segmentation fault on execution of a C program related to strings [duplicate]执行与字符串相关的C程序时出现分段错误[重复]
【发布时间】:2014-08-14 17:48:44
【问题描述】:

我有以下代码。我初始化了 2 个指针,一个在字符串的开头,另一个在字符串的结尾。在每一步之后,我都会增加第一个指针并减少第二个指针。如果通过取消引用第一个指针获得的值小于通过取消引用第二个指针获得的值,我将第一个指针的值复制到第二个。

#include <stdio.h>
#include <string.h>

int main() {
   char *word="aacdbc";
   char *p=word;
   char *q=word+(strlen(word)-1);
   printf("\n%s\n",word);
   int i;
   for(i=1;i<=strlen(word)-1;++i) {
      if(*p<*q) {
         *q=*p;
      }
      ++p;
      --q;
   }
   printf("\n%s\n",word);
   return 0;
}

但代码显示“分段错误错误”。我在哪一行写错了?

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    C(和 C++)中的字符串字面量是不可变的。因此,您尝试更改变量 word 所指向的字符串文字

    char *word = "aacdbc";
    

    有undefined behaviour。

    将定义从指向数组的指针更改

    char word[] = "aacdbc";
    

    程序可能如下所示

    #include <stdio.h>
    
    int main( void )
    {
       char word[] = "aacdbc";
       char *p = word;
       char *q = word+ + sizeof( worrd ) - 1;
    
       printf( "\n%s\n", word );
    
       while ( p < q && p < --q )
       {
          if ( *p < *q ) *q = *p;
          ++p;
       }
    
       printf( "\n%s\n", word );
    
       return 0;
    }
    

    【讨论】:

    • 值得一提的是字符串文字是如何存储在代码段 (RO) 中的,而数组是在堆栈中 (RW)。 stackoverflow.com/questions/16021454/…
    • @Dogbert:这是一个实现细节,可能是这样,也可能不是。
    • @Deduplicator 这种类型的细节在所有符合 ANSI 的 C 编译器中都很常见,并且不限于特定平台或操作系统。
    • @Dogbert:常量文字既不需要池化,也不需要位于代码段中,也不需要位于任何类型的只读部分中。在具有内存保护或只读内存的系统上,大多数编译器会在可能的情况下将它们放在那里,当然,但这不是合同规定的。
    • @Dogbert:嗯,最好的文档实际上是标准。如果您想要一个明确处理该问题的好帖子,请查看以下答案:stackoverflow.com/a/4105123
    【解决方案2】:

    因为word 是一个指向常量(只读)字符序列的指针。换句话说,您不能更改字符串文字的内容。

    如果你想改变它的内容,你应该将word声明为一个字符数组:

    char word[]="aacdbc";
    

    有了这么小的变化,段错误应该会消失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-20
      • 2013-08-31
      • 1970-01-01
      • 2023-03-31
      • 2021-07-18
      • 1970-01-01
      • 2019-08-21
      • 2011-08-08
      相关资源
      最近更新 更多