【问题标题】:What is wrong with my merge sort?我的合并排序有什么问题?
【发布时间】:2014-01-16 10:47:42
【问题描述】:

我想使用指针编写合并排序,但是当我尝试在 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,分段错误。 (很长 地址)在合并排序中(a

然而,当我回溯它时,它会在合并中调用第二个合并排序的行提供无限数量的调用,尽管我不明白为什么这与调用第一个合并排序的地方有任何不同(实际上那一个也在我的 gdb 回溯的第 0 帧中突出显示)

这次我做错了什么?

【问题讨论】:

  • arrone &lt;= q &amp;&amp; arrtwo &lt;= r 无意义
  • 我不知道怎么做。循环继续,直到 arrone 或 arrtwo 点超出其上限。我就是这样检查的。
  • arronearrtwo 是由malloc 返回分配的内存地址。它独立于qr
  • 你是对的,让我来解决这个问题。
  • free(arrone);注意,如果你改了arrone,就不能free(arrone)了。

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


【解决方案1】:

这里的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(..) 中失败。检查所有此类实例。

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

【讨论】:

  • 天哪,这应该是 (r - p)/2。谢谢
  • @TheoChronic 是的,但您还有其他问题。
  • 好吧,我仍然遇到段错误。有什么想法吗?
  • int *arrone = malloc(sizeof(int) * (q - p + 1));你在这里分配了多少元素..你的代码只是每个数组..正确吗?
  • 是的,只是每个阵列。这意味着分配的空间相当于数组 a 的一半。它下面的一个是为了分配另一半。这些子数组由下面的 for 循环填充。
【解决方案2】:

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

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

你心中的逻辑是什么 --- int *q = p + (q - p)/2;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    相关资源
    最近更新 更多