简体   繁体   English

在自底向上合并排序中合并数组时中止陷阱 6

[英]Abort trap 6 when merging arrays in bottom-up Merge Sort

I was trying to implement Merge Sort (Bottom-up approach) until a mysterious Abort trap occurs:我试图实现合并排序(自下而上的方法),直到出现一个神秘的中止陷阱:

void botup_mergesort(int *arr, int begin, int end)
{
    for (int merge_sz = 1; merge_sz < (end - begin); merge_sz *= 2)
    {
        for (int par = begin; par < end; par += merge_sz*2)
        {
            const int &sub_begin = par;
            const int &sub_end = std::min(par + merge_sz*2, end);

            if (sub_end - sub_begin <= 1)
            {
                continue;
            }

            const int& m = par + merge_sz;

            const int &merge_size = sub_end - sub_begin;
            int *aux = new int[merge_size];
            int cnt = -1;

            int p1 = sub_begin;
            int p2 = m;
            while (p2 < end && p1 < m && p2 < sub_end)
            {
                if (arr[p1] <= arr[p2])
                    aux[++cnt] = arr[p1++];
                else if (arr[p1] > arr[p2])
                    aux[++cnt] = arr[p2++];
            }

            while (p1 < m)
            {
                aux[++cnt] = arr[p1++];
            }

            while (p2 < sub_end && p2 < end)
            {
                aux[++cnt] = arr[p2++];
            }

            for (int i = sub_begin, m_cnt = 0; i < sub_end; ++i)
            {
                arr[i] = aux[m_cnt++];
            }
            delete[] aux;
        }
    }
}

void sort(int *arr, int begin, int end) { botup_mergesort(arr, begin, end); }

int main()
{
    int arr[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5};
    // int arr2[] = {2, 2, 2, 2, 2, 8, 5, 3, 9, 4, 6, 2, 1, 5, 1, 5, 7};
    int n = sizeof(arr) / sizeof(int);
    cout << "Size: " << n << endl;

    sort(arr, 0, n);

    print(arr, n);
    return 0;
}

The code works fine for small arrays, ie int arr2[] , but as the array gets bigger, Abort trap comes back.该代码适用于小型数组,即int arr2[] ,但随着数组变大,中止陷阱又回来了。

I tried using the debugger and it returned SIGABRT at delete[] aux;我尝试使用调试器,它在delete[] aux;处返回SIGABRT . . I did a little search on the internet and decided to use std::vector instead of a dynamic array, and it worked.我在互联网上进行了一些搜索,并决定使用std::vector而不是动态数组,并且它有效。 However, I really desired to know what is wrong behind this code.但是,我真的很想知道这段代码背后有什么问题。

My compiler is Apple clang version 11.0.3 on Visual Studio Code.我的编译器是 Visual Studio Code 上的 Apple clang 版本 11.0.3。

Thank you for your help!谢谢您的帮助! Sorry I've forgetten something, I am a inexperienced college student.对不起,我忘记了一些事情,我是一个没有经验的大学生。

The following change will fix the error:以下更改将修复错误:

        const int& m = std::min(par + merge_sz, end);

The code could be a bit faster if a one time allocation of a full sized second array was done, and if the direction of merge was changed on each pass, instead of doing a copy back after each merge.如果完成了一次完整大小的第二个数组的分配,并且如果在每次通过时更改合并方向,而不是在每次合并后进行复制,则代码可能会更快一些。 The code would need to detect if the number of passes is odd, where the last merge would put data into the second array, where it would need to copy the data back to the first array one time.代码需要检测通过的次数是否为奇数,最后一次合并会将数据放入第二个数组,其中需要将数据复制回第一个数组一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM