我正在为 Coursera 的算法:设计与分析类(class) (https://www.coursera.org/course/algo) 编写第一个编程作业。 它涉及使用合并排序来计算反转(http://en.wikipedia.org/wiki/Inversion_(discrete_mathematics))。我认为这相对来说比较简单,因为我之前(在学校)遇到过合并排序。
#include <iostream>
#include <fstream>
using namespace std;
int *half(int *array, int n, int start, int end)
{
/*
* Creates a new array which contains elements from ''array'' starting with ''start''
* and ending with ''end - 1''.
*/
int *new_array = new int[end-start];
for(int i = start; i < end; i++)
{
new_array[i-start] = array[i];
}
return new_array;
}
int merge(int *array1, int n1, int *array2, int n2, int *new_array)
{
/*
* Merges arrays 1 and 2 (with lengths n1 and n2) into a new_array, counting
* ''split inversions'' by the way.
*/
int i = 0, j = 0, count = 0;
for(int k = 0; k < n1 + n2; k++)
{
if(i >= n1)
{
new_array[k] = array2[j];
j++;
continue;
}
if(j >= n2)
{
new_array[k] = array1[i];
i++;
continue;
}
if( array1[i] <= array2[j] )
{
new_array[k] = array1[i];
i++;
}
else
{
new_array[k] = array2[j];
j++;
count++;
}
}
return count;
}
int mergesort(int *array, int n)
{
if(n == 1) return 0; //base case
int x, y, z;
int odd;
if(n%2 == 0) odd = 0;
else odd = 1;
int *half1 = new int [n/2];
int *half2 = new int [n/2 + odd];
half1 = half(array, n, 0, n/2);
half2 = half(array, n, n/2, n);
x = mergesort(half1, n/2);
y = mergesort(half2, n/2 + odd); //if n is odd, we add one
z = merge(half1, n/2, half2, n/2 + odd, array); //we write a sorted array back in our starting array
delete [] half1;
delete [] half2;
return x + y + z;
}
int main()
{
int n;
int *array = new int[n];
cin >> n;
for(int i = 0; i < n; i++)
{
int x;
cin >> x;
array[i] = x;
}
for(int i = 0; i < n; i++)
cout << array[i] << " ";
cout << endl;
cout << "Number of inversions: " << mergesort(array, n) << endl;
for(int i = 0; i < n; i++)
cout << array[i] << " ";
cout << endl;
delete[] array;
return 0;
}
所以,这里有什么奇怪的? 第一件事:对我来说,它对某些数组非常有效,但对其他数组会崩溃(稍后举例)。 第二件事:我向我的 friend 发送了代码,他说他一切正常,即使是对我来说严重崩溃的示例也是如此。
所以,例子:
对于数组 [1 2 3 4 5 6 7] g++ 产生这个:
malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted (core dumped)
当我使用 gdb “回溯”它时:
#0 0x00007ffff7753445 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff7756bab in __GI_abort () at abort.c:91
#2 0x00007ffff779abed in __malloc_assert (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at malloc.c:300
#3 0x00007ffff779e0f4 in sYSMALLOc (av=0x7ffff7ad3720, nb=32) at malloc.c:2448
#4 _int_malloc (av=0x7ffff7ad3720, bytes=12) at malloc.c:3892
#5 0x00007ffff779fa45 in __GI___libc_malloc (bytes=12) at malloc.c:2924
#6 0x00007ffff7b8fded in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff7b8ff09 in operator new[](unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x0000000000400b12 in mergesort (array=0x603010, n=7) at jedan.cpp:81
#9 0x0000000000400cfe in main () at jedan.cpp:120
它对数组 [1 2 3 4 5 6 7 8 9 10] 做了类似的事情(但不相同!),再次连接到 new 和 delete[] 函数。如果有人认为这会有帮助,我可以稍后将其发布在这里,但我不想让这篇文章膨胀太多。 它适用于我尝试过的大多数数组(我对大小 <= 6 的数组没有问题,而且对于相当多的更大数组)。
我正在使用昨天安装的 Ubuntu 12.04……非常干净和新鲜。 帮忙?
附言如果您发现变量名称有点奇怪,抱歉...我将它们从我的母语翻译过来,这样代码可以更具可读性。
最佳答案
int n;
int *array = new int[n]; // Undefined behavior
n
在这里未初始化使用,因此您将获得“随机”长度分配。
如果您不走运并且 n
持有一个“大”垃圾值,您的代码可能看起来有效。如果它的值很小,您可能会在填充初始数组时损坏堆 - 这会产生您所看到的错误类型。
将 cin >> n;
行移动到 array
分配之前。
旁注:我认为您在 mergesort
中进行的两次分配已泄漏(您只是delete
half
中分配的内存code>,如果我正确阅读了你的代码,你实际上不需要在 mergesort
本身中进行分配。
关于c++ - C++ 中涉及 new 和 delete[] 函数的奇怪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11276058/