我正在尝试创建一个带有5个元素的向量的程序,并根据它们的距离对它们进行排序(“距离”意味着除了这里的点之外)。
但每次执行时它都会给我“分段错误”错误:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char ID[8];
char Content[4];
int distance;
} DATA;
void sort(DATA *z, int l){
DATA p; //pivot
DATA t;
int aux=(l-1); //pivot's position
int i,j;
p.distance=z[l-1].distance;
if(l==1){return;}
for(i=0; i<l; i++){
if((z[i].distance)<(p.distance)){
continue;
}
if((z[i].distance)>(p.distance)){
t=z[i];
for(j=i; j<aux; j++){
z[j]=z[j+1];
}
z[aux]=t;
aux--;
}
}
sort(z,aux-1);
sort(&z[aux+1],l-aux);
}
int main(){
DATA *z;
int l=5;
int i;
z=(DATA*)malloc(5*sizeof(DATA));
z[0].distance=5;
z[1].distance=1;
z[2].distance=4;
z[3].distance=3;
z[4].distance=2;
sort(z,l);
for(i=0; i<5; i++){
printf("%d\n",z[i].distance);
}
free(z);
}
我看不出问题出在哪里。如果可以,请帮忙。
答案 0 :(得分:0)
您在不检查第二个参数的值是什么的情况下递归调用sort。 用gdb执行代码产生了这个输出:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400661 in sort (z=0x602010, l=-513) at main.c:21
21 p.distance=z[l-1].distance;
(gdb) bt
#0 0x0000000000400661 in sort (z=0x602010, l=-513) at main.c:21
#1 0x000000000040077c in sort (z=0x602010, l=-511) at main.c:51
#2 0x000000000040077c in sort (z=0x602010, l=-509) at main.c:51
#3 0x000000000040077c in sort (z=0x602010, l=-507) at main.c:51
#4 0x000000000040077c in sort (z=0x602010, l=-505) at main.c:51
#5 0x000000000040077c in sort (z=0x602010, l=-503) at main.c:51
#6 0x000000000040077c in sort (z=0x602010, l=-501) at main.c:51
#7 0x000000000040077c in sort (z=0x602010, l=-499) at main.c:51
#8 0x000000000040077c in sort (z=0x602010, l=-497) at main.c:51
#9 0x000000000040077c in sort (z=0x602010, l=-495) at main.c:51
#10 0x000000000040077c in sort (z=0x602010, l=-493) at main.c:51
#11 0x000000000040077c in sort (z=0x602010, l=-491) at main.c:51
#12 0x000000000040077c in sort (z=0x602010, l=-489) at main.c:51
#13 0x000000000040077c in sort (z=0x602010, l=-487) at main.c:51
#14 0x000000000040077c in sort (z=0x602010, l=-485) at main.c:51
#15 0x000000000040077c in sort (z=0x602010, l=-483) at main.c:51
#16 0x000000000040077c in sort (z=0x602010, l=-481) at main.c:51
#17 0x000000000040077c in sort (z=0x602010, l=-479) at main.c:51
#18 0x000000000040077c in sort (z=0x602010, l=-477) at main.c:51
#19 0x000000000040077c in sort (z=0x602010, l=-475) at main.c:51
#20 0x000000000040077c in sort (z=0x602010, l=-473) at main.c:51
#21 0x000000000040077c in sort (z=0x602010, l=-471) at main.c:51
#22 0x000000000040077c in sort (z=0x602010, l=-469) at main.c:51
您可以使用调试符号编译代码,例如gcc -g main.c
然后用gdb gdb a.out
执行它。加载后只需输入run来运行它,你就会看到分段错误。键入bt作为后跟踪。
答案 1 :(得分:0)
此行看起来很可疑
sort(&z[aux+1],l-aux);
l是长度,aux +是新的基本索引,所以新的长度应该是l - aux -1
然而正如其他人所说,你需要调试/放入诊断printfs。调试像离子屏这样的功能很难。
答案 2 :(得分:0)
正如几条评论所指出的那样,您可以使用gdb来查找Segmentation Fault的位置。我在原始代码上执行了此操作,发现它在行
处断开p.distance=z[l-1].distance; // statement 1
正如Malcolm所指出的,它发生的原因是你在递归调用sort函数时没有正确传递数组的长度。正确的递归调用应该是(记住c数组从零开始)
sort(z,aux); // left half of the array , excluding the pivot
sort(&z[aux+1],l-aux-1); // right half of the array.
此外,理想情况下应在检查后放置声明1,
if(l <= 1){return;}
注意,我如何将比较从l == 1更改为l&lt; = 1,因为您还必须检查l = 0的情况。即使在这些更改之后,遍历数组的循环也存在一些问题,在保持原始代码结构的同时,我试图尽可能地修复它。这是代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char ID[8];
char Content[4];
int distance;
} DATA;
void sort(DATA *z, int l){
DATA p; //pivot
DATA t;
int aux=(l-1); //pivot's position
int i,j;
if(l <= 1){return;}
p.distance=z[l-1].distance;
for(i=0; i<l; i++){
if(i >= aux)
break; // to avoid going over the right of pivot unnecessarily
if((z[i].distance)<(p.distance)){
continue;
}
if((z[i].distance)>(p.distance)){
t=z[i];
for(j=i; j<aux; j++){
z[j]=z[j+1];
}
z[aux]=t;
aux--;
i--; // You have changed the array and brought in a new element ,
//and you should consider it too for comparison with pivot.
}
}
sort(z,aux); // left half of the array , excluding the pivot
sort(&z[aux+1],l-aux-1); // right half of the array.
}
int main(){
DATA *z;
int l=5;
int i;
z=(DATA*)malloc(5*sizeof(DATA));
z[0].distance=5;
z[1].distance=1;
z[2].distance=4;
z[3].distance=3;
z[4].distance=2;
sort(z,l);
for(i=0; i<5; i++){
printf("%d\n",z[i].distance);
}
free(z);
}
但我建议您考虑以不同方式编写遍历循环,因为它现在围绕太多元素移动,实际上是O(n ^ 2)。而 使用quicksort所需的行为是O(n)。我建议在像CLRS算法手册这样的好书中查找算法。