简体   繁体   English

带有分段错误的quicksort程序

[英]quicksort program with segmentation fault

Today I was going through the quick sort algorithm from Algorithms in C by R.Sedgewick. 今天,我正在研究R.Sedgewick编写的C语言中的快速排序算法。

I understood a good chunk of how the algorithm works. 我了解了算法的工作原理。 The coding part just confused me a bit and I got a segmentation fault at the end. 编码部分使我有些困惑,最后我遇到了分段错误。 Here is the code: 这是代码:

#include <stdio.h>
void quicksort(int[], int, int); // prototype

void quicksort(int a[], int l, int r) // What is the value of l. Why hasn't the author 
                                      // mentioned it. Is it the size of the array? 
{
    int i, j, v, t;
    if(r > l)
    {
        v = a[r];
        i = l - 1; // What is l here? Is it the size if yes look at first while statement
        j = r;

        for(;;)
        {

            /*The algorithm says: scan from right until an element < a[r] is found. Where 
              r is the last position in the array. But while checking in the second while
              loop elements > a[r] is searched */

            while (a[++i] < v); // How can you increment again after reaching end of arrray
                                // size if l is the size of the array
            while (a[--j] > v);
            if(i >= j) break;
            t = a[i]; a[i] = a[j]; a[j] = t;
        }
    }

    t = a[i]; a[i] = a[r]; a[r] = t;

    quicksort(a, l, i - 1);
    quicksort(a, i + 1, r);

    return;
}

int main()
{
    int i, a[10]; // assuming size is 10

    for(i = 0; i < 10; i++)
    {
        scanf("%d", &a[i]);
    }

    int l = 10; // I am passing size of the array
    int r = 9; // position of last element

    quicksort(a, l, r);
    return 0;
}

The error is like this. 错误是这样的。 Suppose if I enter 10 elements and then press enter, this is what happens: 假设如果我输入10个元素,然后按Enter,将发生以下情况:

1 4 8 2 3 6 4 7 10 9
segmentation fault.

process returned 139(0x8b)

This is what debugger returned: 这是调试器返回的内容:

Breakpoint 1, quicksort (a=0xbffff808, l=0, r=0) at quick.c:11
11      if(r > 1)
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x080484fb in quicksort (a=0xbffff808, l=0, r=0) at quick.c:28
28      t = a[i]; a[i] = a[r]; a[r] = t;
(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) c
The program is not being run.

The correct way to do the above program is this. 执行上述程序的正确方法是这样。 There is nothing with the left and right pointer. 左右指针什么都没有。 The left pointer should point to 0th location and right pointer to n - 1 location, if array occupies n memory locations. 如果数组占用n个存储位置,则左指针应指向第0个位置,右指针应指向n-1个位置。 I had done a silly mistake by not including the recursive function of quicksort inside the if condition. 通过在if条件中不包括quicksort的递归函数,我犯了一个愚蠢的错误。 Hence all that headache. 因此,所有的头痛。 The correct program is: 正确的程序是:

/* Working quicksort
 * Robert sedgewick best
 */

#include <stdio.h>

void quicksort(int[], int, int); // prototype

void quicksort(int a[], int l, int r) 
{
    int i, j, v, t;
    if(r > l)
    {
        v = a[r];
        i = l - 1;
        j = r;

        for(;;)
       {
            while (a[++i] < v); 
            while (a[--j] > v);

            if(i >= j) break;
            t = a[i]; a[i] = a[j]; a[j] = t;

        } // End for here


    t = a[i]; a[i] = a[r]; a[r] = t;

    quicksort(a, l, i - 1);
    quicksort(a, i + 1, r);

    } /* End if here. That is include the recursive
         functions inside the if condition. Then it works 
         just fine. */

    return;
}

int main()
{
    int i, a[5]; // assuming size is 10

    for(i = 0; i < 5; i++)
    {
        scanf("%d", &a[i]);
    }

    int l = 0; // I am passing size of the array
    int r = 4; // position of last element

    quicksort(a, l, r);

       int s;

    for(s = 0; s < 5; s++)
    {
        printf("%d ", a[s]);
    }
    return 0;
}

Please run in a debugger such as gdb . 请在调试器(如gdb This will show you the exact line your segfault is happening on. 这将向您显示发生段错误的确切行。 If you google "gdb cheatsheet" it will be easy enough to get started. 如果您使用Google“ gdb速查表”,它就足够容易上手了。 Remember to compile with -g flag." 请记住使用-g标志进行编译。”

My session: 我的会议:

dan@dev1:~ $ gcc -g quick.c
dan@dev1:~ $ gdb a.out
...
(gdb) r
Starting program: /home/dan/a.out 
1 4 8 2 3 6 4 7 10 9

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400572 in quicksort (a=0x7fffffffe530, l=10, r=9) at quick.c:21
21              while (a[++i] < v); // How can you increment again after reaching end of arrray

l and r stand for "left" and "right", respectively. lr代表“左”和“右”。

The segmentation fault is happening because you're passing l = 10 , so while (a[++i] < v); 由于您传递了l = 10 ,因此发生了分段错误,因此while (a[++i] < v); breaks. 休息。

[edit] [编辑]

while (a[++i] < v);                                
while (a[--j] > v);

These two loops are also problematic: you need to test that i and j are not out of bounds. 这两个循环也是有问题的:您需要测试ij是否未超出范围。

int a[10];
int l = 10;
int r =  9; 

quicksort(a, l, r);

called quicksort(a, l, r)
//l=10,r=9
if(r > 1) // 9 > 1 is true
{
    i = l - 1;//i = 10 - 1 = 9
    for(;;)
    {
        while (a[++i] < v);//a[++i] is a[9+1] = a[10] is out of range!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM