0

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
Community
  • 1
  • 1
Sergiy Kolodyazhnyy
  • 938
  • 1
  • 13
  • 41

1 Answers1

2

Your sort code copies strings amongst elements of a (originally states), yet not all of those strings are the same size. So, if you were copying something to where Texas was, the copy would go past where Texas ended, thus modify whatever happens to be stored in the space after Texas.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • so in other words, I'd need to actually declare the size of the states array ? like char *states[20] ? – Sergiy Kolodyazhnyy Oct 10 '14 at 01:15
  • 1
    The problem isn't the number of elements in `states`; the problem is the space allocated to each string in that array. One solution would be to change the declaration to `states[4][20]`; this would set aside 20 bytes for each string, and thus each slot would have room for any of the names. Another would be to swap pointers instead of swapping the characters (which would have the added benefit of being faster). – Scott Hunter Oct 10 '14 at 10:55