【问题标题】:Passing an array of strings to a function-segmentation fault将字符串数组传递给函数分段错误
【发布时间】:2015-06-24 00:32:22
【问题描述】:

所以,我在下面编写了这段代码,它应该将一个字符串数组传递给一个函数,然后该函数将数组按字母顺序排序。我知道我完成它的方式可能并不漂亮,但它是用于学校的,我需要将它传递给一个函数并使用strcmp。我遇到了一些问题,但我设法对所有编译错误进行了排序。但是,现在,当我尝试运行该程序时,我收到错误 segmentation fault(core dumped)。有人可以指导我到我犯错的地方吗?

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

void sort(char *str[]);

int main()
{
    char *states[11] = {"Florida", "Oregon", "California", "Georgia"};

    sort(states);

    return 0;
}   

void sort(char *str[])
{
    int x, y;
    char alpha[11] = {0};

  for(x = 1; x < 4; x++){
    for(y = 1; y < 4; y++){
      if(strcmp(str[y - 1], str[y]) > 0){
        strcpy(alpha, str[y - 1]);
        strcpy(str[y - 1], str[y]);
        strcpy(str[y], alpha);
      }
    }
  }

  printf("\nThe states, in order, are: ");
  for(x = 0; x < 4; x++)
    printf("\n%s", str[x]);
} 

【问题讨论】:

    标签: c arrays string strcmp


    【解决方案1】:

    你不能覆盖 strcpy() 会做的字符串文字,修改字符串文字会调用未定义的行为,而是交换指针。

    这个

    strcpy(alpha, str[y - 1]);
    strcpy(str[y - 1], str[y]);
    strcpy(str[y], alpha);
    

    可以正常工作

    alpha = str[y - 1];
    str[y - 1] = str[y];
    str[y] = alpha;
    

    如果您将alpha 声明为

    char *alpha;
    

    另外,请注意字符串的大小不是11 in

    char *states[11];
    

    这是数组可以容纳的指针数量。指针指向字符串文字,在这种情况下,其大小并不重要。重要的是数组包含指针,你可以让指针指向别的地方,但你不能像字符串字面量那样改变静态内存。

    【讨论】:

    • 我对字符串文字的了解不多,非常感谢您提供的信息。进行建议的更改后,一切都按预期工作。
    【解决方案2】:

    添加到 iharob 的答案中,如果所有字符串的长度都处于 11 中,则您的代码应该可以工作。当您的代码尝试将“Oregon”与“California”交换时,它会崩溃。由于“California”的长度为 11 个字节,“Oregon”的长度为 7 个字节(包括空字符),当您使用 strcpy 用“California”覆盖字符串数组“Oregon”时,您的缓冲区溢出并且程序将核心使用信号 11 转储。您可以使用 iharob 建议的方法,也可以更改代码,如下所示:-

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<ctype.h>
    
    void sort(char str[][11]);
    
    int main()
    {
        char states[4][11] = {"Florida", "Oregon", "California", "Georgia"};
    
        sort(states);
    
        return 0;
    }   
    
    void sort(char str[][11])
    {
        int x, y;
        char alpha[11] = {0};
    
      for(x = 1; x < 4; x++){
        for(y = 1; y < 4; y++){
          if(strcmp(str[y - 1], str[y]) > 0){
            strcpy(alpha, str[y - 1]);
            strcpy(str[y - 1], str[y]);
            strcpy(str[y], alpha);
          }
        }
      }
    
      printf("\nThe states, in order, are: ");
      for(x = 0; x < 4; x++)
        printf("\n%s", str[x]);
    } 
    

    产生的输出将是:-

    gaurav@ubuntu:~$ ./a.out 
    
    The states, in order, are: 
    California
    Florida
    Georgia
    Oregon
    

    【讨论】:

    • 您的答案有效,因为您的数组不再是指向字符串文字的指针数组,而是因为您的数组是可写的数组数组。 您不能写入存储字符串文字的位置,即使您将 1 个字节写入 1000000 字节的目标,程序也会调用未定义的行为。
    • 嗨,我认为二维字符数组是可以修改的。我不明白“您无法写入存储字符串文字的位置,即使您将 1 个字节写入具有 1000000 字节的目标,程序也会调用未定义的行为。”。你能澄清更多吗?我建议使用 strcpy 的替代解决方案。
    • 您的回答似乎表明问题是因为目标字符串太小,这是不正确的,那将是另一个问题,在这种情况下使用strcpy() 实际上非常低效。因为您已经使用了strcmp() 并且使用strcpy() 将再次遍历while 字符串。
    • 我想参考问题陈述“将字符串数组传递给函数分段错误”。在我的帖子中,我指出了崩溃发生的原因以及崩溃的可能解决方法是什么。您的解决方案提供了一种不同的方式来实现相同的排序行为。当然,您的解决方案在指针交换方面更有效,而提交者正在使用 strcpy 执行字符串复制。你能告诉我为什么我的假设“目标字符串太小,这是不正确的”是错误的吗?你分析过核心转储的回溯吗?
    • 以下语句根本错误“添加到iharob的答案,如果所有字符串的长度都在11中,你的代码应该可以工作”,所以你可以看到为什么我说你的答案也是错误的,即使你发布的代码显然有效。
    猜你喜欢
    • 2016-12-08
    • 2012-04-12
    • 2014-12-10
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    相关资源
    最近更新 更多