【问题标题】:Quicksort Algorithm giving segmentation fault error快速排序算法给出分段错误错误
【发布时间】:2017-11-04 17:16:18
【问题描述】:

我正在尝试创建一个程序,该程序接受一个包含 5 个元素的向量并根据它们的距离对它们进行排序(“距离”的含义不是这里的重点)。

但是每次我执行它都会给我“segmentation fault”错误:

#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);

}

我看不出问题出在哪里。如果可以的话,请帮忙。

【问题讨论】:

  • 也许是时候学习了how to debug small programs
  • 你用过调试器吗?这是完成这项工作的正确工具。对于初学者,它会立即准确地告诉您哪一行代码导致了段错误。
  • 你推荐哪一个?顺便说一句,感谢您的快速响应!
  • gdb 如果你使用的是 linux。

标签: c algorithm sorting segmentation-fault quicksort


【解决方案1】:

您正在递归调用 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 作为回溯。

【讨论】:

    【解决方案2】:

    这条线看起来很可疑

    sort(&z[aux+1],l-aux);
    

    l 是长度,aux +1 是新的基本索引,所以新的长度应该是 l - aux -1

    但是,正如其他人所说,您需要调试/放入诊断 printfs。像离子屏这样的功能很难调试。

    【讨论】:

      【解决方案3】:

      正如几位 cmets 所指出的,您可以使用 gdb 来查找 Segmentation Fault 的位置。我在你的原始代码上做了这个,发现它在行

      p.distance=z[l-1].distance;  // statement 1
      

      正如 Malcolm 所指出的,这是因为您在对排序函数的递归调用中没有正确传递数组的长度。正确的递归调用应该是(记住 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

      #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)。尽管 使用快速排序所需的行为是它是 O(n) 。我建议在 CLRS 算法书之类的好书中查找该算法。

      【讨论】:

        猜你喜欢
        • 2017-06-20
        • 2021-09-21
        • 2021-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-04
        相关资源
        最近更新 更多