MATLAB 中的 free() 和 mxFree() - 两次释放内存

free() and mxFree() in MATLAB - freeing memory twice

美好的一天, 我有以下代码已经给我带来了一天的问题。 我调试了它,在尝试释放内存之前它工作正常。 free() 函数应该在执行结束时自动调用,所以我把 mxFree() 代码注释掉了,希望能得到一个结果。即使我这样做,程序也会释放内存两次,就像手动释放内存的情况一样 - 因此我得出结论,这是我无法控制的。

*** glibc detected *** /usr/local/MATLAB/R2012a/bin/glnx86/MATLAB: free(): invalid pointer: 0xad2427a1 ***

有什么我遗漏的吗?

注意:我已经尝试了一些带有内存分配的 .mex 文件示例,它们工作正常 - 所以错误在下面,在我的代码中。

/*
Beamforming algorithm
Arguments: xr, yr, zr,
           t, ts, W, U,
       Sdata, NrSensor c, omega_o
Output: S1_sum

S1_sum = beamforming(xr,yr,zr,t,ts,W,U,Sdata,NrSensor,c,omega_o)
*/

#include "mex.h"
#include <stdlib.h>
#include <math.h>

#define INPUT_ARGS 11
#define OUTPUT_ARGS 1

#define Ar(a, b) Ar[b+a*NrSensor]
#define Ai(a, b) Ai[b+a*NrSensor]
#define V(a, b) V[b+a*len_zr]
#define tau(a, b) tau[b+a*NrSensor]
#define tau_s(a, b) tau_s[b+a*len_zr]
#define tau_r(a, b) tau_r[b+a*NrSensor]
#define w(a, b) w[b+a*len_zr]
#define W(a, b) W[b+a*NrSensor]

#define arg(a, b) arg[b+a*len_zr]
#define newrange(a, b) newrange[b+a*len_zr]
#define oldrange(a, b) oldrange[b+a*len_zr]
#define S1_sum_r(a, b, c) S1_sum_r[c+b*len_xr+a*len_yr*len_xr]
#define S1_sum_i(a, b, c) S1_sum_i[c+b*len_xr+a*len_yr*len_xr]
#define Sdata_r(a, b) Sdata_r[b+a*NrSensor]
#define Sdata_i(a, b) Sdata_i[b+a*NrSensor]
#define S1interpr(a, b) S1interpr[b+a*len_zr]
#define S1interpi(a, b) S1interpi[b+a*len_zr]

#define PI_ 3.141592653

double sinc(double x){
  return sin(PI_*x)/(PI_*x);
}

void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
{
  /*
    Declarations
  */
  int xr_, yr_, i, j, m;
  int len_xr, len_yr, len_zr, len_t,
    len_t_, NrSensor, NrSensor_Cen;
  double _t, _i, arg_min, arg_max, norm_factor;
  double start_tau, end_tau, c, omega_o;
  double *xr, *yr, *zr, *t, *ts,
    *Sdata_r, *Sdata_i, *W;
  double *Ar, *Ai, *V, *tau, *tau_r, *tau_s,
    *arg, *U, *w, *t_, *x_r, *x_i, *start_index,
    *newrange, *oldrange, *S1_sum_r, *S1_sum_i,
    *S1interpi, *S1interpr;

  /*
    Checking number of arguments
   */

  if(nrhs != INPUT_ARGS)
    mxErrMsgTxt("Incorrect number of arguments!\n");
  if(nlhs != OUTPUT_ARGS)
    mxErrMsgTxt("Incorrect number of outputs!\n");

  /*
    Reading arguments
   */

  xr = mxGetPr(prhs[0]);
  yr = mxGetPr(prhs[1]);
  zr = mxGetPr(prhs[2]);
  t  = mxGetPr(prhs[3]);
  ts = mxGetPr(prhs[4]);
  W  = mxGetPr(prhs[5]);
  U  = mxGetPr(prhs[6]);
  Sdata_r = mxGetPr(prhs[7]);
  Sdata_i = mxGetPi(prhs[7]);
  NrSensor = (int) mxGetScalar(prhs[8]);
  c = mxGetScalar(prhs[9]);
  omega_o = mxGetScalar(prhs[10]);

  len_xr = mxGetN(prhs[0]);
  len_yr = mxGetN(prhs[1]);
  len_zr = mxGetN(prhs[2]);
  len_t  = mxGetM(prhs[3]);

  /*
    Initialisations
  */
  _t     = 0.0;
  len_t_ = 0;
  NrSensor_Cen = NrSensor/2;
    /*
Space allocation and checking


 */
  arg   = malloc(sizeof(double)*len_zr*len_t);
  Ar    = malloc(sizeof(double)*len_zr*NrSensor);
  Ai    = malloc(sizeof(double)*len_zr*NrSensor);
  V     = malloc(sizeof(double)*len_zr*3);
  tau   = malloc(sizeof(double)*len_zr*NrSensor);
  tau_s = malloc(sizeof(double)*len_zr*3);
  tau_r = malloc(sizeof(double)*len_zr*NrSensor);
  U     = malloc(sizeof(double)*3);
  w     = malloc(sizeof(double)*len_zr*3);
  W     = malloc(sizeof(double)*NrSensor*3);
  ts    = malloc(sizeof(double)*len_zr);
  t     = malloc(sizeof(double)*len_t);
  t_    = malloc(sizeof(double)*len_t);
  x_r   = malloc(sizeof(double)*len_t);
  x_i   = malloc(sizeof(double)*len_t);

  arg      = malloc(sizeof(double)*len_zr*len_t);
  newrange = malloc(sizeof(double)*len_zr*len_t);
  oldrange = malloc(sizeof(double)*len_zr*len_t);

  S1interpr = malloc(sizeof(double)*NrSensor*len_zr);
  S1interpi = malloc(sizeof(double)*NrSensor*len_zr);
  start_index = malloc(sizeof(double)*len_t);
  /*
    S1_sum_r = mxMalloc(len_xr*len_yr*len_zr);
    S1_sum_i = mxMalloc(len_xr*len_yr*len_zr);
  */

  int dim_S1_sum[3] = {len_xr, len_yr, len_zr};
  plhs[0] = mxCreateNumericArray(3, dim_S1_sum, 
                 mxDOUBLE_CLASS,
                 mxCOMPLEX);
  S1_sum_r = (double*) mxGetPr(plhs[0]);
  S1_sum_i = (double*) mxGetPi(plhs[0]);

  if(arg   == NULL ||
     Ar    == NULL ||
     Ai    == NULL ||
     V     == NULL ||
     tau   == NULL ||
     tau_s == NULL ||
     tau_r == NULL ||
     U     == NULL ||
     W     == NULL ||
     w     == NULL ||
     ts    == NULL ||
     t     == NULL ||
     t_    == NULL ||
     x_r   == NULL ||
     x_i   == NULL ||
     start_index == NULL ||
     newrange == NULL ||
     oldrange == NULL ||
     S1_sum_r == NULL ||
     S1_sum_i == NULL ||
     S1interpr == NULL||
     S1interpi == NULL){
    mxErrMsgTxt("Malloc error!\n");
    return;
  }


  /*
    --- INITIALISING S1interp, S1_sum, tau, full of zeros
   */

  for(i=0; i<NrSensor; i++){
    for(j=0; j<len_zr; j++){
      S1interpr(i,j) = 0;
      S1interpi(i,j) = 0;
    }
  }

  for(i=0; i<len_xr; i++){
    for(j=0; j<len_yr; j++){
      for(m=0; m<len_zr; m++){
    S1_sum_r(i,j,m) = 0;
    S1_sum_i(i,j,m) = 0;
      }
    }
  }

  for(i=0; i<NrSensor; i++){
    for(j=0; j<len_zr; j++){
    tau(i,j) = 0;
    }
  }

  /*
    --- MAIN ALGORITHM ---
   */
  for(xr_=0; xr_ < len_xr; xr_++){
    for(yr_=0; yr_ < len_yr; yr_++){

      for(i=0; i < len_zr; i++){
        V(0, i) = xr[xr_];
    V(1, i) = yr[yr_];
    V(2, i) = zr[i];
      }

      for(i=0; i < len_zr; i++){
    tau_s(0, i) = V(0, i) - U[0];
    tau_s(1, i) = V(1, i) - U[1];
    tau_s(2, i) = V(2, i) - U[2];
      }

      for(m=0; m < NrSensor; m++){
    for(i=0; i < len_zr; i++){
      /*
        I see no point of the squeeze function
        since W is already of known sizes
      */
      w(0, i) = V(0, i) - W(0, m);
      w(1, i) = V(1, i) - W(1, m);
      w(2, i) = V(2, i) - W(2, m);
    }

    for(i=0; i< len_zr; i++){
      /*
        sum(w.*w)
      */
      _t = w(0, i)*w(0,i) +
        w(1, i)*w(1,i) +
        w(2, i)*w(2,i);

      tau_r(m, i) = sqrt(_t)/c;
    }
      }

      for(m=0; m < len_zr; m++){
    for(i=0; i < NrSensor; i++){
      /*
        Computing sum(tau_s(m, :).*tau_s(m, :))
      */
      _t = tau_s(0, m)*tau_s(0, m) +
        tau_s(1, m)*tau_s(1, m) +
        tau_s(2, m)*tau_s(2, m);

      tau(i, m) = tau_r(i, m) + sqrt(_t)/c;
    }
      }

      /*
    for(i=0; i < len_zr; i++){
    for(j=0; j < NrSensor; j++){
    Tau(i,j)=tau(i,j);
    }
    }
      */

      for(i=0; i < len_zr; i++){
    for(j=0; j < NrSensor; j++){
      Ar(i,j)=cos(omega_o * tau(i, j));
      Ai(i,j)=sin(omega_o * tau(i, j));
    }
      }

      /*
    --- BIG LOOP AHEAD ---
       */
      for(m=0; m < NrSensor; m++){
    start_tau = tau(NrSensor_Cen, 1);
    end_tau = tau(NrSensor_Cen, len_zr);

    /*
      Finding index : writing start indexes
      and also t_ array
    */
    len_t_=0;

    for(i=0; i<len_t; i++){
      if(t[i] >= start_tau &&
         t[i] <= end_tau){
        start_index[len_t_] = i;
        t_[len_t_] = t[i];
        x_r[len_t_] = Sdata_r(i, m);
        x_i[len_t_] = Sdata_i(i, m);
        len_t_++;
      }
    }

    for(i=0; i < len_zr; i++){
      ts[i]=tau(m, i);
    }

    for(i=0; i < len_t_; i++){
      for(j=0; j < len_zr; j++){
        newrange(i, j) = ts[j];
      }
    }

    for(i=0; i < len_zr; i++){
      for(j=0; j < len_t_; j++){
        oldrange(j, i) = t_[j];
      }
    }

    for(i=0; i < len_t_; i++){
      for(j=0; j < len_zr; j++){
        arg(i, j) = newrange(i, j)-oldrange(i, j);
      }
    }

    arg_min = arg[0];
    for(i=0; i < len_t_; i++)
      for(j=0; j < len_zr; j++)
        if(arg_min>arg(i, j))
          arg_min=arg(i, j);

    arg_max = arg[0];
    for(i=0; i < len_t_; i++)
      for(j=0; j < len_zr; j++)
        if(arg_max<arg(i, j))
          arg_max=arg(i, j);


    norm_factor = (2*len_t_)/(arg_max-arg_min);

    for(i=0; i < len_zr; i++){
      _t = 0; 
      for(j=0; j < NrSensor; j++){
        _t = sinc(arg(i, j)*norm_factor)*x_r[j];
      }

      S1interpr(m, i) = Ar(m, i) * _t;

      _t = 0; 
      for(j=0; j < NrSensor; j++){
        _t = sinc(arg(i, j)*norm_factor)*x_i[j];
      }

      S1interpi(m, i) = Ai(m, i) * _t;
    }
      }

      for(i=0; i < len_zr; i++){
    _t = 0;
    for(j=0; j < NrSensor; j++){
      _t += S1interpr(j, i);
    }

    S1_sum_r(xr_, yr_, i) = _t;

    _t = 0;
    for(j=0; j < NrSensor; j++){
      _t += S1interpi(j, i);
    }

    S1_sum_i(xr_, yr_, i) = _t;
      }

    }
  }

  free(arg);
  free(Ar);  
  free(Ai);
  free(V);   
  free(tau); 
  free(tau_s);
  free(tau_r);
  free(U);   
  free(w);   
  free(W);   
  free(ts); 
  free(t);     
  free(t_);   
  free(x_r);   
  free(x_i);   

  free(newrange); 
  free(oldrange);

  free(S1interpr);
  free(S1interpi);
  free(start_index);
  return;
}

编辑

我已经删除了除开头(直到内存分配)和内存释放之外的所有代码。我现在也在使用 malloc() 和 free()。在内存分配和释放之间,我还放了这段代码:

  for(i=0; i<NrSensor; i++){
    for(j=0; j<len_zr; j++){
      S1interpr(i,j) = 0;
      S1interpi(i,j) = 0;
    }
  }


  for(i=0; i<NrSensor; i++){
    for(j=0; j<len_zr; j++){
    tau(i,j) = 0;
    }
  }

第一个循环没有问题。但是,第二个显然破坏了变量 V (在它之前声明)和在它之后声明的那个。而且,按照我的逻辑,它似乎没有超过任何一种界限...

第二个循环没有为 tau 正确索引。您将 tau 的索引定义为

 #define tau(a, b) tau[b+a*NrSensor]

假设 NrSensor = 10 且 len_zr = 5,让我们遍历第二个循环。对于这种情况,循环变量 i 的最大值为 9,循环变量 j 的最大值为 4。现在,

tau(9,4) => tau[4+9*10] => tau[94].

但是你正在分配 tau

tau   = malloc(sizeof(double)*len_zr*NrSensor);

样本值 10 和 5 是

tau   = malloc(sizeof(double)*50)

您需要更改 tau 的索引定义以交换 a 和 b,或者更改循环 i 和 j 的顺序。