【问题标题】:Memory leak in recursive function递归函数中的内存泄漏
【发布时间】:2012-10-31 01:34:05
【问题描述】:

这是我用 C 语言实现 Cooley-Tukey 算法的一个 sn-p。是的,这是大学作业。但无论如何......该算法工作正常,但我必须释放 ar1 和 ar2 以消除大量输入数据上的巨大内存泄漏,但每次我尝试时,我都会得到无效读取。理论上,ar1 和 ar2 应该只由函数的当前实例使用,并且它们应该是唯一的,因为每个实例都分配自己的输出。

complex_exp * dft(complex_exp * from, int N, int s, int inverse) {

if(N == 1)
    return from;

int i;
complex_exp * transformed = (complex_exp *) malloc(N * sizeof(complex_exp));
complex_exp * ar1 = dft(from, N / 2, 2*s, inverse); //LINE 83
complex_exp * ar2 = dft(from + s, N / 2, 2*s, inverse); // LINE 84

for(i = 0; i < N/2; i++) {

    transformed[i] = ar1[i]; //LINE 88
}

for(i = N/2; i < N; i++) {
    transformed[i] = ar2[i - N/2];
}

//Do stuff with the transformed array - NO reference to ar1 or ar2.

free(ar1); //LINE 113
return transformed;
}

Valgrind 说:

==69597== Invalid read of size 8
==69597==    at 0x100000EE6: dft (progtest05.c:88)
==69597==    by 0x100000EA2: dft (progtest05.c:84)
==69597==    by 0x100000E67: dft (progtest05.c:83)
==69597==    by 0x100000E67: dft (progtest05.c:83)
==69597==    by 0x100001A0E: main (progtest05.c:233)
==69597==  Address 0x100007250 is 64 bytes inside a block of size 256 free'd
==69597==    at 0xDCB8: free (vg_replace_malloc.c:450)
==69597==    by 0x1000011E5: dft (progtest05.c:113)
==69597==    by 0x100000E67: dft (progtest05.c:83)
==69597==    by 0x100000E67: dft (progtest05.c:83)
==69597==    by 0x100000E67: dft (progtest05.c:83)
==69597==    by 0x100001A0E: main (progtest05.c:233)

因此,第 83 行对 dft 的调用似乎释放了内存,然后在下一行对 dft 的调用尝试访问该内存。知道实际发生了什么以及如何消除泄漏吗?

【问题讨论】:

  • 你不应该释放transformed而不是ar1吗? (虽然那时你不能退货)
  • @Pubby 我不能释放它,因为我要退回它,确定吗?
  • 这不是泄漏。您正在尝试访问您已经释放(在第 113 行)的内存(在第 88 行)。
  • 如果我不释放它就是泄漏。除非我无处可做。
  • 对不起,我明白了,您将 valgrind 输出解释为指向泄漏。

标签: c memory recursion fft memory-leaks


【解决方案1】:

您说“每个实例都分配自己的输出”,但在此声明中并非如此:

if(N == 1)
    return from;

也许当 N==1 时,您应该返回 from 的副本(即 malloc 新内存,将 from 的内容复制到新内存中,然后返回副本)。

我怎样才能摆脱泄漏?

我希望你必须释放 ar1 和 ar2 才能返回转换。

【讨论】:

  • 没错,返回一个新数组而不是 from 就可以了。
【解决方案2】:

解决这些问题的最佳方法是明确定义前置条件和后置条件。您是否假设返回的结果已被 malloc 处理?如果是这样,您似乎通过返回“from”以及未能释放“ar2”来违反此规定。如果你假设返回的结果不是 malloc 的,那么你需要确保这块内存是由调用者提供的,并且不返回 malloc 的内存。

【讨论】:

    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 2021-07-11
    • 2017-05-09
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 2014-12-21
    • 2012-08-31
    相关资源
    最近更新 更多