在递归合并排序期间中止(核心转储)

Posted

技术标签:

【中文标题】在递归合并排序期间中止(核心转储)【英文标题】:Aborted (core dumped) during recursive merge sort 【发布时间】:2020-09-26 21:46:20 【问题描述】:

在通过引用传递时实现递归合并排序时遇到问题。 basic_merge_sort 是 main.cpp 的入口点,我通过值传递,因为我使用相同的数组进行一堆排序。我得到的错误是malloc(): invalid size (unsorted) Aborted (core dumped),使用 gcc 和 Makefile。使用 Counter 类的静态成员也可以在递归期间跟踪比较。我也尝试不使用指针,而是使用静态类成员向量,但没有运气。有什么想法或建议吗?提前致谢。

#include "merge.hpp"
#include "selection.hpp"

using namespace std;

int Counter::count0; //lets start count from 0

int basic_merge_sort(vector<double> holder_array) //entry point

    int end = holder_array.size() - 1;
    mpartition(&holder_array, 0, end);
    return Counter::count;


void merge_sort(vector<double> *holder_array, int start, int end, int middle)

    int i = start, j = middle + 1, k = 0;
    vector<double> temp(end - start + 1, 0.0); 

    while (i <= middle && j <= end)
    
        if (holder_array->at(i) < holder_array->at(j))
        
            temp[k] = holder_array->at(i); 
            k++;
            i++;
            Counter::count++;
        
        else
        
            temp[k] = holder_array->at(j);
            k++;
            j++;
            Counter::count++;
        
    

    while (i <= middle)
    
        temp[k] = holder_array->at(i);
        k++;
        i++;
        Counter::count++;
    

    while (j <= end)
    
        temp[k] = holder_array->at(j);
        k++;
        j++;
        Counter::count++;
    
    for (i = start; i <= end; i++)
    
        holder_array->at(i) = temp[i - start];
    


void mpartition(vector<double> *holder_array, int start, int end)

    int middle;
    if (start < end)
    
        middle = (start + end) / 2;
        mpartition(holder_array, start, middle);
        mpartition(holder_array, middle + 1, end);
        merge_sort(holder_array, start, end, middle);
    

【问题讨论】:

显示的代码中至少有一个明显的错误。不幸的是,它不符合minimal reproducible example 的要求,因此无法权威地回答这是唯一的问题。可能还有其他人,因此需要minimal reproducible example 才能最终回答这个问题。请edit您的问题,以便显示的代码符合minimal reproducible example的所有要求。如需更多帮助,请在此处查看 ***.com 的 help center 和 How to Ask 问题。 vector&lt;double&gt; temp[end - start + 1]; 这是什么? @Quimby 是存储元素的临时存储,它将返回到原始向量,我们需要它,因为我们使用递归 afaik。 @SamVarshavchik 感谢您的快速回复,您能说说明显的错误是什么吗?我也错过了我的问题不符合最小可重现示例的要求的点,我提到 basic_merge_sort 是从 main.cpp 调用的,它通过值传递给 vector 。我需要包含我的库吗?我的 main.cpp?我真的不明白这里缺少什么是可重现的。 *temp aka temp[0] 是一个空向量。 temp-&gt;at(k)(相当于(*temp).at(k)temp[0].at(k))对于k的任何值都会抛出std::out_of_range异常 【参考方案1】:

您的代码中存在多个问题:

您没有通过引用传递向量:basic_merge_sort 获取向量的副本,因此不会对传递给它的数组进行排序,而只是对副本进行排序。 mpartition 接受一个指向向量的指针,这与通过引用传递并不完全相同。 排除 end 的约定令人困惑且容易出错,您应该在 C++ 中使用更惯用的约定并考虑排除上限。

这是修改后的版本:

#include "merge.hpp"
#include "selection.hpp"

using namespace std;

int Counter::count0; //lets start count from 0

int basic_merge_sort(vector<double>& array)

    mpartition(array, 0, array.size());
    return Counter::count;


void merge_sort(vector<double>& array, size_t start, size_t middle, size_t end)

    size_t i = start, j = middle, k = 0;
    vector<double> temp(end - start, 0.0); 

    while (i < middle && j < end) 
        if (array[i] < array[j]) 
            temp[k++] = array[i++]; 
            Counter::count++;
         else 
            temp[k++] = array[j++];
            Counter::count++;
        
    

    while (i < middle) 
        temp[k++] = array[i++];
        Counter::count++;
    

    while (j < end) 
        temp[k++] = array[j++];
        Counter::count++;
    
    for (i = start; i < end; i++) 
        array[i] = temp[i - start];
    


void mpartition(vector<double>& array, size_t start, size_t end)

    if (end - start >= 2) 
        size_t middle = start + (end - start) / 2;
        mpartition(holder_array, start, middle);
        mpartition(holder_array, middle, end);
        merge_sort(holder_array, start, middle, end);
    

【讨论】:

以上是关于在递归合并排序期间中止(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章

合并排序代码中的分段错误

使用链表合并排序 C 实现

count swap / comparisons合并排序算法的数量

合并排序、快速排序和树遍历中的递归

Python 归并排序(递归非递归自然合并排序)

算法导论中,为啥合并排序的递归树的高度为lgn?