C 整数快速排序,rand()中的分段错误
我正在为整数编写一个快速排序算法,在srand函数中出现了一个奇怪的segfault错误。以下是sort.h中的代码:C 整数快速排序,rand()中的分段错误,c,srand,C,Srand,我正在为整数编写一个快速排序算法,在srand函数中出现了一个奇怪的segfault错误。以下是sort.h中的代码: int distributePivot (int *a, int left, int pivot, int right) { int i, j; if (pivot != right) swapInt(&pivot, &right); i = left; j = right - 1; while (i &l
int distributePivot (int *a, int left, int pivot, int right) {
int i, j;
if (pivot != right)
swapInt(&pivot, &right);
i = left;
j = right - 1;
while (i < j) {
while (i < j && a[i] <= a[right])
i++;
while (j > i && a[j] >= a[right])
j--;
if (i < j)
swapInt(&a[i], &a[j]);
}
if (i < right)
swapInt(&a[i], &a[right]);
return i;
}
void intArrayQuickSort (int *a, int left, int right) {
int pivot;
if (left < right) {
pivot = rand() % (right - left +1) + left;
pivot = distributePivot(a, left, pivot, right);
intArrayQuickSort (a, left, pivot -1);
intArrayQuickSort (a, pivot, right);
}
}
其中temp
是指向整数的指针
这是我在gdb中执行时得到的错误:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff77e9884 in rand () from /lib64/libc.so.6
你能帮帮我吗
多谢各位
编辑:这是交换函数:
void swapInt (int *a, int *b) {
int aux = *a;
*a = *b;
*b = aux;
}
应该是:
pivot = left + rand() % (right - left +1);
甚至可能:
pivot = left +1 + rand() % (right - left);
事实上,我已经找到了一个解决方案,但我不知道它为什么有效。 第二个递归调用应该是:
intArrayQuickSort (a, pivot + 1, right);
这对于算法来说是有意义的,但我不明白为什么rand()会出现错误。有什么解释吗?程序逻辑有错误。
例如
总的来说
数组=[1,2]
调用数组快速排序(数组,0,1);//a:数组,左:0,右:1
在数组中快速排序
pivot=1//
rand()%(右-左+1)+左的临时结果代码>
调用distributePivot(a,0,1,1)
在distributePivot中
不交换(pivot,右),因为pivot==righit
i=0//左
j=0//右-1
由于i==j
执行交换(a[i],a[right]),因为i
//a=[2,1]/!!NG
返回0
//已处于非法状态
在数组中快速排序
枢轴=0//从返回值:0
调用数组快速排序(a,0,-1)//左:0,枢轴-1:-1
无操作返回
调用数组快速排序(a,1,1)//枢轴+1:1,右:1
无操作返回
总的来说
结果:a=[2,1]//NG 我认为
int distributePivot (int *a, int left, int pivot, int right) {
int i, j;
if (pivot != right)
swapInt(&a[pivot], &a[right]);
i = left;
j = right - 1;
while (1) {
while (i < right && a[i] < a[right])
i++;
while (left <= j && a[j] >= a[right])
j--;
if (i < j)
swapInt(&a[i], &a[j]);
else
break;
}
if(i < right)
swapInt(&a[i], &a[right]);
return i;
}
void intArrayQuickSort (int *a, int left, int right) {
int pivot;
if (left < right) {
pivot = rand() % (right - left +1) + left ;
pivot = distributePivot(a, left, pivot, right);
intArrayQuickSort (a, left, pivot - 1);
intArrayQuickSort (a, pivot + 1, right);
}
}
int-distributePivot(int*a,int-left,int-pivot,int-right){
int i,j;
如果(枢轴!=右)
swapInt(&a[支点],&a[右]);
i=左;
j=右-1;
而(1){
而(i
Oops,我也是。也许这就是我添加第三个的原因?事实上,我得到了与你所有的可能性相同的错误。为什么他们和我的不一样?也许是错的。在您的情况下,我将执行一些printf()调试。这可能是一个由一个关闭,在某个地方。顺便说一句:在大多数情况下,如果只使用无符号类型进行索引,这会有所帮助。(包装时,unsigned将变为0xfffffffffffff,这将在第一次发生故障时,在造成任何实际损坏之前)很可能您正在覆盖某个缓冲区;您是否在Valgrind下运行了此功能?如果您选择一个pivot而不使用rand(),问题是否会消失?我们是否可以在distributePivot
中看到swapInt(&pivot,&right)函数代码>您需要swapInt(&a[pivot]、&a[right])
。这可能是堆栈溢出:重复太深,因此对rand
的函数调用会从堆栈末尾运行,并试图非法访问内存,因此会出现segfault(您可以尝试将任何函数放在rand
之前,看看这是否会在新函数中导致相同的问题)@Zagorax-该程序进行此更改也是不正确的。你可以看到我的answers@dbaupp-但在这种情况下,并不是rand()函数产生堆栈溢出,而是一些超出范围的类似赋值。需要检查程序本身的逻辑。谢谢,在解决另一个错误后,我已经发现了这个错误。现在我的函数可以工作了。@Zagorax-这个故事是在更改为intArrayQuickSort(a,pivot+1,右)之后发生的代码>。您的程序逻辑仍然错误。@Zagorax-如果您已经解决了问题,则删除该问题。或者,如果出现错误,请编辑问题的代码,修复程序仍在运行。@BLUEPRIX-Oh该死。你是对的。当我只有两个元素时,我有50%的机会失败(因为递归,我总是失败)。我修好了。非常感谢你。我是否应该修改问题中的代码,或者它足以将您的答案标记为正确答案?我不喜欢中途中断。你的解决方案似乎有效,但我的老师总是说要避免这种情况。看看我在聊天室里贴的那个。“这一个也能起作用,也能起作用。@Zagorax-我之所以选择中断,是因为有重复的I
是令人不愉快的。像你想做的那样做很好。
intArrayQuickSort (a, pivot + 1, right);
int distributePivot (int *a, int left, int pivot, int right) {
int i, j;
if (pivot != right)
swapInt(&a[pivot], &a[right]);
i = left;
j = right - 1;
while (1) {
while (i < right && a[i] < a[right])
i++;
while (left <= j && a[j] >= a[right])
j--;
if (i < j)
swapInt(&a[i], &a[j]);
else
break;
}
if(i < right)
swapInt(&a[i], &a[right]);
return i;
}
void intArrayQuickSort (int *a, int left, int right) {
int pivot;
if (left < right) {
pivot = rand() % (right - left +1) + left ;
pivot = distributePivot(a, left, pivot, right);
intArrayQuickSort (a, left, pivot - 1);
intArrayQuickSort (a, pivot + 1, right);
}
}