如何在这个递归函数中避免malloc?

时间:2015-06-27 17:03:35

标签: c memory-management recursion

我在C中实现了以下工作(正确输出)递归fft。我在递归函数中使用malloc,这肯定会导致一些丢失的内存,但我不知道如何避免它。我见过的大多数其他递归算法都将相同的内存传递给递归调用(就地称我认为它已被调用),但我无法做到这一点。这种内存泄漏的直接解决方案将是很好的,但是相关材料的链接也将非常受欢迎。

float complex *fft(float complex *in, int n, float complex w) {
  int i,j;
  if(fabs(crealf(w)-1.00f)<.0001f && fabs(cimagf(w)-0.00f)<0.0001f) {
    return in;
  }
  float complex *ine = malloc(n/2*sizeof(float complex));
  float complex *ino = malloc(n/2*sizeof(float complex));
  for(i=0,j=0;i<n;i++) {
    if(i%2==0){ 
      ine[j]=in[i];
    }
    else {
      ino[j++]=in[i];
    }
  }
  float complex *s = fft(ine,n/2,cpow(w,2));
  float complex *s1 = fft(ino,n/2,cpow(w,2));

  float complex *bad = malloc(n*sizeof(float complex));
  for (j=0; j<n/2; j++){
    bad[j] = s[j] + cpow(w,j) * s1[j];
    bad[j+n/2] = s[j] - cpow(w,j) * s1[j];
  }
  free(ine); free(ino);
  return bad;
}

还会返回一个指向在被认为是不良实践的函数内分配的内存的指针,因为它将它留给调用者释放该内存?

我尝试注册代码审核,但注册按钮不适用于我的古老浏览器。

1 个答案:

答案 0 :(得分:0)

问题在于bad,因为递归函数的调用实例不知道递归调用是返回传递的参数,还是新分配的指针bad。其他两个指针ineino没有问题,因为它们在分配它们的实例中总是free d。

我正在编写一个解决方案来管理分配的bad指针数组,这些指针可以在程序结束时释放,当时我遇到了更好的解决方案。

添加一个新参数 int *newptr,通知调用者是否返回指针free,因为此指针不会传递回递归堆栈。

float complex *fft(float complex *in, int n, float complex w, int *newptr) {
  int i,j;
  int mem=0, mem1=0;                                    // added these flag vars
  if(fabs(crealf(w)-1.00f)<.0001f && fabs(cimagf(w)-0.00f)<0.0001f) {
    return in;                                          // no memory was allocated
  }
  float complex *ine = malloc(n/2*sizeof(float complex));
  float complex *ino = malloc(n/2*sizeof(float complex));
  for(i=0,j=0;i<n;i++) {
    if(i%2==0){ 
      ine[j]=in[i];
    }
    else {
      ino[j++]=in[i];
    }
  }
  // recursion starts here
  float complex *s = fft(ine,n/2,cpow(w,2), &mem);      // added extra arg
  float complex *s1 = fft(ino,n/2,cpow(w,2), &mem1);    // added extra arg

  float complex *bad = malloc(n*sizeof(float complex));
  *newptr = 1;                                          // flag memory allocated
  for (j=0; j<n/2; j++){
    bad[j] = s[j] + cpow(w,j) * s1[j];
    bad[j+n/2] = s[j] - cpow(w,j) * s1[j];
  }
  free(ine); free(ino);
  if (mem)
      free(s);                                          // free returned mem
  if (mem1)
      free(s1);                                         // free returned mem
  return bad;                                           // with newptr set
}