Search code examples
cstringsortingbubble-sort

Sort in alphabetically order random names in C


I try to sort alphabetically some names but get the "Segmentation Fault (core dumped)" error when I try to copy one string to another using bubble sort method. Here is my code:

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

int main() {
    char *string[] = {"Nickole", "Bolden", "Eldon", "Darcie", "Lisette", "Furr", "Parthenia", "Tunison", "Andrew", "Michael"};
    char *hold;
    int compare_a, compare_b;
    for(int j = 0; j < 9; j++) {
        for(int i = 0; i < 9; i++) {
            compare_a = string[i][0];
            compare_b = string[i+1][0];
            if( compare_a > compare_b) {           
                strcpy(hold, string[i+1]);
                strcpy(string[i+1], string[i]);
                strcpy(string[i], hold);
            }
        }
    }
    for(int i = 0; i < 9; i++) {
        printf("%s ", string[i]);
    }
    return 0;
}

Solution

  • The strings you have in your program are string literals. Literals are like constants and attempts to modify them leads to undefined behaviour though they are not specified as const. They may be placed in a part of memory from which the program will only be able to read but not write.

    You attempt to modify the memory where the string literals are stored with your strcpy()s. You got a segmentation fault because you invoked undefined behaviour.

    Now your program would've worked had you declared the strings like

    char string[][10] = {"Nickole", "Bolden", "Eldon", "Darcie", "Lisette", "Furr", "Parthenia", "Tunison", "Andrew", "Michael"};
    

    I gave the size as 10 as the longest string here is of length 9. One byte extra for the \0 character indicating end of string.

    This is because they are not string literals and may be modified.

    See this post.

    As Code-Apprentice suggested in the comments you could swap the values of pointers instead of attempting to swap string literals.

    if( compare_a > compare_b) {
        hold=string[i];
        string[i]=string[i+1];
        string[i+1]=hold;
    }
    

    Also, you can use strcmp() for comparing strings instead of just comparing the first character of the strings like

    if( strcmp(string[i], string[i+1])>0 ) {
        hold=string[i];
        string[i]=string[i+1];
        string[i+1]=hold;
    }
    

    strcmp() returns positive value if the second string is before the first in the lexicographical order.