【问题标题】:Segmentation fault in C using GCC compiler while performing quicksort [closed]在执行快速排序时使用 GCC 编译器在 C 中出现分段错误 [关闭]
【发布时间】:2015-09-01 06:57:48
【问题描述】:

我编写了以下 C99 代码来对固定数组执行快速排序。但是,在打印初始数组后,它给出了分段错误。我现在没有任何调试器,我使用 KWrite,然后使用终端来编译和运行。这是代码。

#include <stdio.h>
#define LEN 8

int arr[8] = {3,5,7,1,2,4,6,8};

void printarr()
{
    printf("\n");
    for (int i = 0; i<LEN; i++)
        printf("\t %d", arr[i]);
    printf("\n");
}


void quicksort(int _left,int _right)
{
    int left = _left;
    int right = _right;
    int pivot = (left+right)/2;

    while (left<=right)
    {
        while(pivot>arr[left])
            left--;
        while (pivot<arr[right])
            right++;
        if(left<=right)
        {
            int temp = arr[right];
            arr[right] = arr[left];
            arr[left] = arr[temp];
            left++;
            right--;
        }
    }

    if (_left<right)
        quicksort(_left, right);
    else
        quicksort(left, _right);
}

int main()
{
    int left = 0, right = LEN-1;

    printf("Unsorted array:");
    printarr();

    quicksort(left,right);

    printf("Sorted array:");
    printarr();
}

请看一下,让我知道代码的哪一部分导致了这个问题。

【问题讨论】:

  • 嗯,首先,您正在比较pivot,一个在leftright(也是索引)之间计算的索引,与值 来自数组(arr[left]arr[right])。还是太明显了?这需要调试器的业务端。
  • 你应该已经安装了gdb,使用它。 BTW KWrite 不是程序员的编辑器,它是一个文字处理器。你最好使用 Kate。
  • KWrite 和 Kate 使用相同的文本编辑器引擎,它也用于 KDevelop,但与 KWrite 相比,Kate 确实对项目中的多个文件和内置代码完成等事情有更好的处理。 KWord,或今天的 Calligra Words,更像是一个文字处理器。
  • 调试的第一步:使用尽可能简单的测试用例。从对单元素列表进行排序开始。它非常简单,您无需编译即可手动浏览代码。

标签: c gcc fedora quicksort c99


【解决方案1】:

至少,

int temp = arr[right];
arr[right] = arr[left];
arr[left] = arr[temp];

不会做你认为会做的事。

您将值(不是索引)存储到第一行的temp 中,然后在第三行将其用作索引。这根本不会有好的结局。

相反,您想将该值用作 值:

int temp = arr[right];
arr[right] = arr[left];
arr[left] = temp;

您在比较pivot(索引)和arr[right]/arr[left](值)时遇到了类似的问题。

那些设置leftright 的循环也会引起悲伤。您应该递增 left,因为您想将它发送到数组的末尾,并且出于类似原因递减 right

【讨论】:

  • 谢谢。我纠正了这一点。但是,错误似乎仍然存在。
【解决方案2】:

在您的代码中,left = 0 在您的 quicksort 函数中。而且,

while(pivot>arr[left])
        left--;

这里,在这段代码中,left 将变为负值,如果pivot 值大于arr[left],即arr[0]。这很可能导致您的代码为seg fault

我认为根据您的代码,正确的版本应该是

while(pivot>arr[left])      //elements < pivot on the left side
    left++;
while (pivot<arr[right])   //elemenst > pivot in the right side
    right--;

注意

还请理解,我在您的递归调用中找不到任何终止条件

当满足特定条件时,您会希望递归结束。在这种情况下当_left &gt;= _right。这应该在开始时检查以确保您的函数不会进入无限递归。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 2019-12-31
    相关资源
    最近更新 更多