Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 整数快速排序,rand()中的分段错误_C_Srand - Fatal编程技术网

C 整数快速排序,rand()中的分段错误

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

我正在为整数编写一个快速排序算法,在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 < 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);
    }
}