Passing an array of strings to a function-segmenta

2019-09-09 13:06发布

问题:

So, I've written this code below that is supposed to pass an array of strings to a function, which then sorts the array into alphabetical order. I know the way I've done it probably isn't pretty, but it is for school and I'm required to pass it to a function and make use of strcmp. I ran into some problems, but I managed to get all the compile errors sorted. Now, however, when I try to run the program, I get the error segmentation fault(core dumped). Can someone guide me to where I made my mistake?

#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]);
} 

回答1:

You can't overwrite string literals which is what strcpy() would be doing, modifying string literals invokes undefined behavior, instead swap the pointers.

This

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

would work just fine like

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

if you declare alpha as

char *alpha;

Also, notice that the size of the strings is not 11 in

char *states[11];

It's the number of pointers the array can hold. The pointers point to string literals, whose size is not really important in this case. The important thing is that the array contains pointers, and you can make pointers point somewhere else, but you can't change static memory like the one occupied by string literal.



回答2:

Adding to the answer by iharob, your code should work if the lengths of all the string in states in 11. Your code crashes when it is trying to swap "Oregon" with "California". Since the length of "California" is 11 bytes and the length of "Oregon" is 7 bytes (including the null character), when you use strcpy to overwrite string array "Oregon" with "California" your buffer overruns and the program will core dump with signal 11. You could use the approach suggested by iharob or you could change the code like following:-

#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]);
} 

The output produced will be:-

gaurav@ubuntu:~$ ./a.out 

The states, in order, are: 
California
Florida
Georgia
Oregon