任务:我正在开发一个程序,该程序应使用 gnome 排序对字符串数组进行排序(rosettacode.com 上提供了相关代码)
问题:编译代码后,没有报错,但是当我执行程序时,打印出未排序的数组,并且出现“segmentation fault(core dumped)”错误:
____( 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
我无法弄清楚问题出在哪里。排序功能肯定有问题,只是无法弄清楚到底是什么。
源代码:
#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;
}
更新:所以我找到了一种使程序运行的方法。正如这里的用户正确提到的那样,我必须使传递的字符串都具有相同的大小,并使用 this post here 实现了这一点。但是当程序进入排序功能时,我仍然遇到问题。
更新代码 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 }
更新后的输出:
$ ./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)
最终解决方案: 堆栈粉碎可能是因为字符串大小不够大,我有点被另一个 stackoverflow post 暗示了。该程序现在可以像我想要的那样工作,但不知道为什么字符串必须是 30 个字符长,因为最大的字符串 - Washington - 是 10 个字符长,远低于 20 个字符。
最终代码:
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 }
最终输出:
$ ./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
最佳答案
您的排序代码在 a
(最初是 states
)的元素之间复制字符串,但并非所有这些字符串的大小都相同。因此,如果您要将某些内容复制到 Texas
所在的位置,则副本将越过 Texas
结束的位置,从而修改 Texas 之后存储在空间中的任何内容
。
关于c - 字符串数组和 Gnome 排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26290281/