c - 为什么这个快速排序实现给出正确的输出而不是垃圾值?

标签 c segmentation-fault quicksort indexoutofboundsexception

在这段快速排序代码中,如果输入数组正在递减,例如 5 4 3 2 1 ,则变量 i 会继续递增而不进行检查并超出数组范围。这不应该产生段错误吗?正如回复中指出的,即使它没有给出段错误,为什么它不将 arr[j] 与 arr[i] 中的垃圾值(其中 i 超出范围)交换?

int HoarePartition(int a[],int l,int r)
{
    int p,i,j,temp;
    p=a[l],i=l,j=r+1;
    do
    {
        do
        {
            i++;
        }while(a[i]<p);
        do
        {
            j--;
        }while(a[j]>p);
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }while(i<j);
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
    temp=a[l];
    a[l]=a[j];
    a[j]=temp;
    return j;
}

这与快速排序函数一起为 5 4 3 2 1 的输入数组或类似的递减数组提供正确的排序数组。

最佳答案

Shouldn't that give segmentation error?

没有。段错误未指定为捕获超出进程内各个数组或其他对象边界的错误。在拥有它们的操作系统上,它们被指定为捕获使用不正确的进程权限访问内存的错误,例如尝试在进程有权读取的内存范围之外进行读取,尝试在进程有权读取的内存范围之外进行写入。进程有权写入,或尝试执行该进程有权执行的内存范围之外的指令。

当一个进程有两个数组时,ab ,然后阅读a[i]i延伸到 a 之外进入b不会产生段错误,因为该进程有读取 b 的权限。当进程有数组 a 时在为其堆栈分配(和映射)的内存中,然后读取 a[i]i延伸到 a 之外但仍在其堆栈空间内,不会产生段错误。

Why does the code give correct output?

交换后立即 a[i]a[j]里面do循环后,例程立即将它们交换回来,反转更改。这是因为,曾经i超出范围,i<j是假的,因为 jr+1 开始并递减,所以我们知道它在范围内,因此小于 i 。所以循环 while(i<j)终止,以及紧随其后的代码,交换 a[i]a[j] ,被执行。

因此,只要没有发生段错误,任何与数组外部元素的交换都会立即反转,并且不会产生持久影响。

关于c - 为什么这个快速排序实现给出正确的输出而不是垃圾值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76401426/

相关文章:

c - 信号处理程序返回并恢复程序执行

c - 帮忙解决以下情况

c - execvp : bad address error

c - 使用 SDL_image 保存 PNG 时出现段错误

c - 为什么我的指针数组在 C 中有段错误?

java - 按数组中字符串的长度快速排序

c - QuickSort 不排序.. C

c - 如何只用cmake编译c?

Printf() 和 Scanf() 的 C 段错误

c++ - C++ 大数快速排序堆栈溢出