在这段快速排序代码中,如果输入数组正在递减,例如 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?
没有。段错误未指定为捕获超出进程内各个数组或其他对象边界的错误。在拥有它们的操作系统上,它们被指定为捕获使用不正确的进程权限访问内存的错误,例如尝试在进程有权读取的内存范围之外进行读取,尝试在进程有权读取的内存范围之外进行写入。进程有权写入,或尝试执行该进程有权执行的内存范围之外的指令。
当一个进程有两个数组时,a
和b
,然后阅读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
是假的,因为 j
从 r+1
开始并递减,所以我们知道它在范围内,因此小于 i
。所以循环 while(i<j)
终止,以及紧随其后的代码,交换 a[i]
和a[j]
,被执行。
因此,只要没有发生段错误,任何与数组外部元素的交换都会立即反转,并且不会产生持久影响。
关于c - 为什么这个快速排序实现给出正确的输出而不是垃圾值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76401426/