我的合并排序有什么问题?

时间:2014-01-16 10:47:42

标签: c sorting pointers segmentation-fault dynamic-memory-allocation

我想使用指针编写合并排序,但是当我尝试在C中执行它时,我遇到了分段错误。我期待一个分段错误,但不是我真正得到它的地方。这是我的代码:

#include <stdio.h>
#include <stdlib.h>


int *merge(int [], int *, int *, int *); 
int *mergesort(int [], int *, int *); 

int main(){
    int n[] = {4, 2, 9, 5, 10, 11, 1, 0}; 
    int *m = mergesort(n, n, n + 7); 

    int i;
    for(i = 0; i < 7; i++)
        printf("[%d]\n", n[i]); 

    return 0;

}

int *mergesort(int *a, int *p, int *r){
    if(p >= r)
        return a; 

    int *q = p + (q - p)/2;
    mergesort(a, p, q); 
    mergesort(a, q+1, r); 

    return merge(a, p, q, r);   
}
/*0, 1, 2, 3, 4, 5, 6, 7*/
int *merge(int *a, int *p, int *q, int *r){
    /*int *arrone = new int[q - p + 1]; 
    int *arrtwo = new int[r - q]; */

    int *arrone = malloc(sizeof(int) * (q - p + 1));
    int *arrtwo = malloc(sizeof(int) * (r - q)); 

    int i;
    for(i = 0; p + i <= q; i++)
        arrone[i] = p[i]; 

    for(i = 0; q + i + 1 <= r; i++)
        arrtwo[i] = *(q + 1 + i); 

    int j;
    for(j = 0; arrone <= q && arrtwo <= r; j++){
        if(*arrone < *arrtwo)
            a[j] = *arrone, arrone++; 
        else
            a[j] = *arrtwo, arrtwo++; 
    }

    if(arrone <= q)
        for(; p + j <= r; j++)
            a[j] = *arrone++; 
    else
        for(; p + j <= r; j++)
            a[j] = *arrtwo++;

    free(arrone);
    free(arrtwo);

    return a; 
}

现在奇怪的部分是我在第一次调用mergesort时得到了这个分段错误。在DDD中,它触及此功能的第二个错误输出。 DDD给了我这个

  

编程接收信号SIGSEGV,分段故障。 (很长   mergesort中的一个地址(一个&lt; =错误读取变量:无法访问   地址为0x7fffff7feff8的存储器,p =&lt;错误读取变量:不能   访问内存0x7fffff7feff0,r =&lt;错误读取变量:不能   在地址0x7fffff7fefe8处访问内存(在mergesort的行)   开始定义)

然而,当我回溯它时,它在合并中调用第二个mergesort的行提供无限量的调用,虽然我不明白为什么与第一个调用的位置有任何不同(实际上那个也在我的gdb backtrace的第0帧中突出显示)

这次我做错了什么?

2 个答案:

答案 0 :(得分:3)

这里q是什么?您声明*q并在表达式中使用q进行初始化。

int *q = p + (q - p)/2;

此外,

a[j] = *arrtwo++;   <-- Here increment of pointer is happening instead of value

应该用作

a[j] = (*arrtwo)++;

因此随后在free(..)失败。检查所有这些实例。

我认为你的指针增量逻辑可以是正确的,但你不能释放更新的指针,它可能指向其他所有东西。

答案 1 :(得分:0)

问题在这里----- int * q = p +(q - p)/ 2;

在初始化q之前将值赋给* q所以q具有垃圾值,而上面的语句会将垃圾值赋给* q。

你在想什么逻辑--- int * q = p +(q - p)/ 2;

相关问题