2011-05-04 133 views
1

我正在尝试编写一个RLS过滤器的MATLAB/mex代码来练习我的C语言,当然,如果我设法让这个过程加快代码速度,但是,尝试运行带有输入的以下代码时,出现分段错误错误。分割错误错误

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

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{  
    /* Macros for input data */ 
    #define xData prhs[0] /* Input signal to filter */ 
    #define dData prhs[1] /* Desired output signal */ 
    #define deltaData prhs[2] /* For initializing covariance matrix */ 
    #define lambdaData prhs[3] /* Forgetting factor */ 
    #define MData prhs[4] /* Filter order */ 

    /* Macros for output data */ 
    #define wData plhs[0] /* Final filter coefficients */ 
    #define yData plhs[1] /* Filter output signal vector */ 
    #define eData plhs[2] /* Error vector */ 
    #define WData plhs[3] /* Filter coefficients matrix */ 

    /* Variables */ 
    mxArray *xT, *P, *q, *k; /* Temp arrays */ 
    double *xr, *xi, *dr, *di, delta, lambda; 
    double *Pr, *Pi, *qr, *qi, *kr, *ki, *xTr, *xTi, den; 
    double *wr, *wi, *yr, *yi, *er, *ei, *Wr, *Wi; 
    int M, Mx, Md, Nx, Nd, m, n, m1, m2, nT, l; 

    /* Get pointers to input data */ 
    xr = mxGetPr(xData); /* Real */ 
    xi = mxGetPi(xData); /* Imag */ 
    dr = mxGetPr(dData); /* Real */ 
    di = mxGetPi(dData); /* Imag */ 
    delta = mxGetScalar(deltaData); 
    lambda = mxGetScalar(lambdaData); 
    M = (int)mxGetScalar(MData); 

    /* Get dimensions of input data */ 
    Mx = mxGetM(xData); /* Number of rows in x */ 
    Nx = mxGetN(xData); /* Number of columns in x */ 
    Md = mxGetM(dData); /* Number of rows in d */ 
    Nd = mxGetN(dData); /* Number of columns in d */ 

    /* Temporary vector - size M-by-1 */ 
    xT = mxCreateDoubleMatrix(M, 1, mxCOMPLEX); 
    xTr = mxGetPr(xT); /* Real */ 
    xTi = mxGetPi(xT); /* Imag */ 

    /* Covariance matrix - size M-by-M */ 
    P = mxCreateDoubleMatrix(M, M, mxCOMPLEX); 
    Pr = mxGetPr(P); /* Real */ 
    Pi = mxGetPi(P); /* Imag */ 

    /* Temporary vector for computing gain vector - size M-by-1 */ 
    q = mxCreateDoubleMatrix(M, 1, mxCOMPLEX); 
    qr = mxGetPr(q); /* Real */ 
    qi = mxGetPi(q); /* Imag */ 

    /* Gain vector - size M-by-1 */ 
    k = mxCreateDoubleMatrix(M, 1, mxCOMPLEX); 
    kr = mxGetPr(k); /* Real */ 
    ki = mxGetPi(k); /* Imag */ 

    /* Create output vector - size Mx-by-1 */ 
    yData = mxCreateDoubleMatrix(Mx, 1, mxCOMPLEX); 
    yr = mxGetPr(yData); /* Real */ 
    yi = mxGetPi(yData); /* Imag */ 

    /* Create error vector - size Mx-by-1 */ 
    eData = mxCreateDoubleMatrix(Mx, 1, mxCOMPLEX); 
    er = mxGetPr(eData); /* Real */ 
    ei = mxGetPi(eData); /* Imag */ 

    /* Create coeff. vector - size M-by-1 */ 
    wData = mxCreateDoubleMatrix(M, 1, mxCOMPLEX); 
    wr = mxGetPr(wData); /* Real */ 
    wi = mxGetPi(wData); /* Imag */ 

    /* Create coeff. matrix - size M-by-Mx */ 
    WData = mxCreateDoubleMatrix(M, Mx, mxCOMPLEX); 
    Wr = mxGetPr(WData); /* Real */ 
    Wi = mxGetPi(WData); /* Imag */ 

    m2 = 0; 
    /* Initialize covariance matrix */ 
    for(m1 = 0; m1 < M; m1++, m2++) 
    { 
     Pr[m1*M+m2] = (1/delta); /* diag(P) = (1/delta) */ 
     Pi[m1*M+m2] = (1/delta); /* diag(P) = (1/delta) */ 
    } 

    for(n = 0; n < Mx; n++) 
    { 
     /* Compute xT_m = [x[n] x[n-1] .... x[n-(M-1)]] */ 
     for(m = 0; m < M; m++) 
     {/* Assume zeros outside available data and zero-fill*/ 
      if(n < (M-1)) 
      { 
       nT = n; 
       for(l = 0; l < M; l++) 
       { 
        xTr[l] = xr[nT]; /* Real */ 
        xTi[l] = xi[nT]; /* Imag */ 
        if(nT == 0) 
         break; 
        else 
         nT--; 
       } 
      } /* Data available for all lags */ 
      else 
      { 
       xTr[m] = xr[n-m]; /* Real */ 
       xTi[m] = xi[n-m]; /* Imag */ 
      } 
      /* Set to zero prior to filling for computing gain vector */ 
      qr[m] = 0; /* Real */ 
      qi[m] = 0; /* Imag */ 
     } 
    } 
    return; 
} 

Atm我已经删除了大量的代码,因为我设法找出错误来自哪里;如果我在下面的代码中注释掉以下部分,它会运行(但对我来说没用)。我试图打印出阵列中使用的索引,看它们中的一个是否为负数,但没有运气。所以我真的找不到错误。最有可能的事情是愚蠢的,但我无法找出错误是什么。我也在下面的另一个函数中使用相同的代码片段(用于LMS过滤器),并且它在那里工作,因为它应该。这两个函数的主要区别在于处理所需的临时数组的数量。所以最大的问题是:有没有人看到代码中的任何明显的错误应该导致seg。故障? (否则我知道代码可能不是那么好,但随着时间的推移,我写了更多的C我认为)。

for(m = 0; m < M; m++) 
{/* Assume zeros outside available data and zero-fill*/ 
    if(n < (M-1)) 
    { 
     nT = n; 
     for(l = 0; l < M; l++) 
     { 
      // xTr[l] = xr[nT]; /* Real */ 
      // xTi[l] = xi[nT]; /* Imag */ 
      if(nT == 0) 
       break; 
      else 
       nT--; 
      } 
    } /* Data available for all lags */ 
    else 
    { 
      // xTr[m] = xr[n-m]; /* Real */ 
      // xTi[m] = xi[n-m]; /* Imag */ 
    } 
    /* Set to zero prior to filling for computing gain vector */ 
    qr[m] = 0; /* Real */ 
    qi[m] = 0; /* Imag */ 
} 
+0

哇你有很多指针那里有宏,以及可能在任何地方。调试器说什么? – ColWhi 2011-05-04 14:04:25

+0

我很惊讶,打印索引不显示错误,我会尽管你有一个索引< 0 or >比你的数组的最大大小。 – ColWhi 2011-05-04 14:14:07

+0

你使用什么尺寸?是否有可能导致内存不足('mxCreateDoubleMatrix'返回'NULL')?如果评论未使用的数组(k,yData,eData,wData,WData),会发生什么情况? – 2011-05-04 14:20:25

回答

1

您确实有很多指针,所以它们中的任何一个都可能导致分段错误。

从你做的debbuging,最有可能的问题是在一个在下面的指针:

XTR,XTI,XR或喜;

所有这些都使用函数mxGetPr()或mxGetPi()进行初始化。不知道它做了什么,这是不可能的。你确定它返回一个指向数组的指针吗?你确定两个数组都至少有m个元素吗?

这是一个非常复杂的结构,因此完全分析所有找到错误的指针是一件复杂的工作。

+0

感谢您的快速回复。你对关于指针的评论再次检查一切,确实这是一个愚蠢的愚蠢的错误。 我已经编写了代码,以便处理复杂数值的数据,但是由于一些愚蠢的原因,我从MATLAB传递给mex网关的数据是实值的(可能忘记从其他测试中更改函数)使指针指向数据的虚数部分导致seg.faults。 所以请注意自我是在所有函数的开头使用数据类型(真实/复杂)的检查,以避免这种愚蠢的错误。:) – drgz 2011-05-04 14:33:09

+0

只是好奇...不应该为复杂的数字算法工作真正的数字,因为'R'是'C'的子集? – 2011-05-05 14:59:46

+0

事实上,他们应该对这种情况稍作修改(即实际数据需要更少的变量,因为数组只需要一个指针)。这可能是mex API的制作结果。 – drgz 2011-05-05 21:58:58