我的代码泄露了.我怎么解决它呢?
My code is leaking. How can I solve it?
我的代码正在泄漏。我应该删除数组的某个地方,我在这行中分配的东西: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);
}
我记得我在一个严重泄漏的应用程序上进行了紧急处理:
- 需要快速加载的改进
- 应用程序已经泄漏,尽管不那么严重
- 已知非回归是不完整的
- 应用程序从未在valgrind下运行(在valgrind下运行多线程代码具有严格的超时依赖关系是很重要的…)
那么,我做了什么?我使用grep
并从代码(*)中删除对new
的所有调用。
- 在c++ 03:
delete
是一个错误(**)和new
是一个代码气味 - 在c++ 11:
delete
和new
都是一个错误(**)
你可以用:
-
std::vector
用于动态分配数组 -
std::unique_ptr
用于动态分配对象 std::shared_ptr
在一些罕见和神秘的情况下,对象的实际生命周期遵循复杂的规则(*)或者如果它是c++ 11,在c++ 03中,在没有完美转发和可变模板的情况下,拥有
C++03中的make_auto_ptr
是不可能的。(**)可能会被认为是编写
boost::scoped_ptr
(或同等)的专家可能需要它;在c++ 11中,你可以在unique_ptr
之上构建任何抽象,因为它是零成本的。
这些正在泄漏:
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;
}
在您尝试解决实现中的内存泄漏问题之前,请考虑这个问题:每次调用merge()
时真的有必要为out_array
分配内存吗?
我认为答案是否定的,相反,为辅助数组分配内存(与arr
大小相同)一旦在merge_sort()
中就足够了,并将此数组传递给merge()
。这种方法可以大大减少内存分配的次数,并且更容易管理内存分配。
如果您想这样分配内存,您应该使用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的回答那样添加删除。
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 在java中解决这段代码时面临循环中的问题
- visual c++,如何获取解决方案目录中的代码
- 为什么这段代码不起作用,我该如何解决?
- 我无法在Visual Studio代码中使用CIN输入答案,它说输入您的年龄,但它说只读文本编辑器如何解决这个问题?
- 从排序数组中删除重复项,具有不同代码方式的相同解决方案具有不同的输出
- 我正在尝试解决一个需要数组总和值但代码不起作用的问题,我想做这样的事情
- 从代码力解决 dp 问题 - 剪彩
- 卡在代码中,同时在代码厨师中解决可能会烹饪
- C++ LeetCode #377 的 DP 解决方案中,此代码是否有错误?
- 给定使用 Bitmask 的解决方案,我无法理解代码中标记的条件评估
- 如何解决C++中声纳库贝静态代码分析错误"Explicitly define the missing copy constructor, move constructor .."
- 使用多态性解决代码重复问题
- 我可以知道如何解决代码中的错误吗?
- 如何解决C++代码中的内存泄漏问题
- 如何解决代码中的以下错误
- 如何解决C代码中"runtime error exitcode 6"报告的错误?
- 如何解决代码中未声明的错误
- 如何解决 C++ 代码中的编译错误
- 我如何解决代码力121A