Task: I am working on a program that should sort array of strings with gnome sort ( code for which is provided on rosettacode.com )
Problem: After compiling the code, no errors reported, however when I execute the program, the unsorted array prints, and I get "segmentation fault(core dumped)" error:
____( 6:46PM)[Sergiy@Ubuntu]:_____ ~> ./a.out
Unsorted: state 0: California state 1: Oregon state 2: Washington state 3: Texas zsh: segmentation fault (core dumped) ./a.out
I cannot figure out what's the problem. Definitely something wrong with the sorting function, just can't figure out what exactly.
Source Code:
#include<stdio.h>
#include<string.h>
void
gnome_sort (char *a[], int n)
{
  int i = 1, j = 2;
  char temp[20];
//#define swap(i, j) { t = a[i]; a[i] = a[j]; a[j] = t; } 
  while (i < n)
    {
      if (strcmp (a[n - 1], a[n]) > 0)
    {
      //swap(i - 1, i);
      strcpy (temp, a[i]);
      strcpy (a[i], a[i - 1]);
      strcpy (a[i - 1], temp);
      if (--i)
        continue;
    }
      i = j;
      j++;
    }
//# undef swap
}
int
main ()
{
  char *states[] = { "California", "Oregon", "Washington", "Texas" };
  int num_states = 4;
 // int n;
//n=sizeof a / sizeof a[0];
//printf("n is %d ",n);
  int i;
  printf ("\n Unsorted:\n");
  for (i = 0; i < num_states; i++)
    {
      printf ("state %d: %s\n", i, states[i]);
    }
  gnome_sort (states,num_states);
  printf ("\n Sorted: \n");
  for (i = 0; i < num_states; i++)
    {
      printf ("state %d: %s\n", i, states[i]);
    }
  return 0;
}
Update: So I have figured out one way to make the program work. As users here properly mentioned, I had to make the string passed all have same size, and achieved that using this post here. But I still have issues when the program gets to the sorting function.
Updated code 1 #include 2 #include
 3  void
 4  gnome_sort (char states[][20], int n)
 5  {
 6    int i = 0, j = 2;
 7    char temp[20];
 8    while (i < n)
 9      {
10        printf ("\n *** Inside while loop *** \n");
11        printf ("\n %d", strcmp (states[i - 1], states[i]));
12        if (strcmp (states[i - 1], states[i]) < 0)
13      {
14        strcpy (temp, states[i]);
15        printf ("\n %s \n", temp);
16        strcpy (states[i], states[i - 1]);
17        strcpy (states[i - 1], temp);
18        if (--i)
19          continue;
20      }
21        i = j;
22        j++;
23      }
24    printf ("\n Sorted in gnome sort: \n");
25    for (i = 0; i < n; i++)
26      {
27        printf ("state %d: %s\n", i, states[i]);
28      }
29  //end of function
30  }
31  int
32  main ()
33  {
34    char states[][20] = { "Washington", "Colorado", "Iowa", "Texas" };
35    int num_states = 4;
36    // int n;
37  //n=sizeof a / sizeof a[0];
38  //printf("n is %d ",n);
39    int i;
40    printf ("\n Unsorted:\n");
41    for (i = 0; i < num_states; i++)
42      {
43        printf ("state %d: %s\n", i, states[i]);
44      }
45    gnome_sort (states,num_states);
46  /*  printf ("\n Sorted: \n");
47    for (i = 0; i < num_states; i++)
48      {
49        printf ("state %d: %s\n", i, states[i]);
50      }*/
51    return 0;
52  }
Updated output:
$ ./a.out
 Unsorted:
state 0: Washington
state 1: Colorado
state 2: Iowa
state 3: Texas
 *** Inside while loop *** 
 -87
 Washington 
 *** Inside while loop *** 
 -87
 Washington 
 *** Inside while loop *** 
 18
 *** Inside while loop *** 
 -6
 Iowa 
 *** Inside while loop *** 
 -73
 Iowa 
 *** Inside while loop *** 
 -17
 Texas 
 *** Inside while loop *** 
 -84
 Texas 
 *** Inside while loop *** 
 -11
 Texas 
 Sorted in gnome sort: 
state 0: Texas
state 1: Iowa
state 2: 
state 3: Colorado
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped) 
Final Solution: Stack smashing was probably because string size wasn't large enough, which i kind of got hinted by another stackoverflow post. The program now works like i wanted, but have no idea why strings had to be 30 characters long, because largest string - Washington - is 10 characters long , which is way below 20.
Final code:
1   #include<stdio.h>
     2  #include<string.h>
     3  void
     4  gnome_sort (char states[][30], int n)
     5  {
     6    int i = 1, j = 2;
     7    char temp[30];
     8    while (i < n)
     9      {
    10        printf ("\n *** Inside while loop *** \n");
    11        printf ("\n %d", strcmp (states[i - 1], states[i]));
    12        if (strcmp (states[i - 1], states[i]) > 0)
    13      {
    14        strcpy (temp, states[i]);
    15        printf ("\n %s \n", temp);
    16        strcpy (states[i], states[i - 1]);
    17        strcpy (states[i - 1], temp);
    18        if (--i)
    19          continue;
    20      }
    21        i = j;
    22        j++;
    23      }
    24    printf ("\n Sorted in gnome sort: \n");
    25    for (i = 0; i < n; i++)
    26      {
    27        printf ("state %d: %s\n", i, states[i]);
    28      }
    29  //end of function
    30  }
    31  int
    32  main ()
    33  {
    34    char states[][30] = { "Washington", "Colorado", "Iowa", "Texas" };
    35    int num_states = 4;
    36    // int n;
    37  //n=sizeof a / sizeof a[0];
    38  //printf("n is %d ",n);
    39    int i;
    40    printf ("\n Unsorted:\n");
    41    for (i = 0; i < num_states; i++)
    42      {
    43        printf ("state %d: %s\n", i, states[i]);
    44      }
    45    gnome_sort (states,num_states);
    46  /*  printf ("\n Sorted: \n");
    47    for (i = 0; i < num_states; i++)
    48      {
    49        printf ("state %d: %s\n", i, states[i]);
    50      }*/
    51    return 0;
    52  }
Final Output:
$ ./a.out
 Unsorted:
state 0: Washington
state 1: Colorado
state 2: Iowa
state 3: Texas
 *** Inside while loop *** 
 20
 Colorado 
 *** Inside while loop *** 
 14
 Iowa 
 *** Inside while loop *** 
 -6
 *** Inside while loop *** 
 3
 Texas 
 *** Inside while loop *** 
 -11
 Sorted in gnome sort: 
state 0: Colorado
state 1: Iowa
state 2: Texas
state 3: Washington
 
     
    