我的代码漏了。我应该删除数组的某个地方,我在这行中分配的内容:
T* out_array = new T[size1+size2];
但我不知道在哪里以及如何。
有人可以帮帮我吗?
代码:
#include <iostream>
using namespace std;
template <class T>
T* merge(T arr1[], int size1, T arr2[], int size2);
template <class T>
T* merge_sort(T arr[], int n)
{
if(n < 2){return arr;}
int mid = n/2;
T *arr1 = merge_sort<T>(arr,mid);
T *arr2 = merge_sort<T>(arr+mid,n-mid);
return merge(arr1, mid, arr2, n-mid);
}
template <class T>
T* merge(T arr1[], int size1, T arr2[], int size2)
{
int i = 0,j = 0;
T* out_array = new T[size1+size2];
while((i < size1) && (j < size2))
{
if(arr1[i] >= arr2[j])
{
out_array[i+j] = arr2[j];
++j;
}
else
{
out_array[i+j] = arr1[i];
++i;
}
}
while(i < size1)
{
//copy the reminder
out_array[i+j] = arr1[i];
i++;
}
while( j < size2)
{
out_array[i+j] = arr2[j];
j++;
}
return out_array;
}
int main()
{
int a[] = {2, 42, 3, 7, 1};
int *a2 = merge_sort(a,5);
for (int i = 0; i<= 4 ; ++i) cout << a2[i] << endl;
delete[] a2;
return (0);
}
答案 0 :(得分:1)
这些都在泄漏:
T *arr1 = merge_sort<T>(arr,mid);
T *arr2 = merge_sort<T>(arr+mid,n-mid);
修复:
template <class T>
T* merge_sort(T arr[], int n)
{
if(n < 2){return arr;}
int mid = n/2;
T *arr1 = merge_sort<T>(arr,mid);
T *arr2 = merge_sort<T>(arr+mid,n-mid);
T * res = merge(arr1, mid, arr2, n-mid);
delete[] arr1;
delete[] arr2;
return res;
}
答案 1 :(得分:1)
在尝试解决实现中的内存泄漏问题之前,请考虑以下问题:每次调用out_array
时是否真的有必要为merge()
分配内存?
我认为答案是否定的,相反,在arr
中为辅助数组分配内存(与merge_sort()
相同)一次就足够了,并传递此数组到merge()
。这种方法可以大大减少内存分配的次数,并且更容易管理内存分配。
答案 2 :(得分:1)
我记得在紧急情况下干预&#34;对于泄漏严重的应用程序:
那么,我做了什么?我使用grep
并从代码(*)中删除了对new
的所有调用。
delete
是错误(**)而new
是代码气味delete
和new
都是错误(**)并不奇怪,所有内存泄漏都消失了!
您可以使用:
,而不是使用newstd::vector
表示动态分配的数组std::unique_ptr
表示动态分配的对象 std::shared_ptr
在一些罕见且神秘的情况下,对象的实际生命周期遵循复杂的规则
(*)或者我可以拥有它,如果它是C ++ 11,在C ++ 03中,并且在没有完美转发和变量模板的情况下,make_auto_ptr
实际上是不可能的。
(**)在C ++ 03中,可以认为专家写boost::scoped_ptr
(或等价物)可能需要它;在C ++ 11中,您可以在unique_ptr
之上构建每个抽象,因为它的成本为0。
答案 3 :(得分:0)
如果要分配这样的内存,则应使用std::unqiue_ptr
。改变
T* out_array = new T[size1+size2];
到
std::unique_ptr<T[]> out_array(new T[size1 + size2]);
更改merge_sort
签名以返回unique_ptr<T[]>
,修复arr1和arr2类型,并且不要手动删除它。这种方法比使用delete[]
更好,因为可以在T operator =
中生成异常。比,delete[]
运算符永远不会被调用,即使你在Erik的答案中添加了删除,你仍然会泄漏内存。