C MEX函数没有';t初始化左侧值

C MEX函数没有';t初始化左侧值,c,matlab,mex,C,Matlab,Mex,我必须使用一个MEX函数,它应该分配一个矩阵并填充它(例如,生成一个单位矩阵)。下面是一个代码示例: #include <stdlib.h> #include "mex.h" void sample(int n, double** T) { (*T) = (double*)malloc(n*n*sizeof(double)); int i, j; if ((*T) == NULL) { return; }

我必须使用一个MEX函数,它应该分配一个矩阵并填充它(例如,生成一个单位矩阵)。下面是一个代码示例:

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

void sample(int n, double** T)
{
     (*T) = (double*)malloc(n*n*sizeof(double));  
     int i, j;
     if ((*T) == NULL)
     {
        return;
    }
    else
    {
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                if (i != j)
                    (*T)[i*n + j] = 0;
                else 
                    (*T)[i*n + j] = 1;
             }
        }
    }
}

void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    mwSize n = *(mwSize*)mxGetData(prhs[0]);
    double *T;

    plhs[0] = mxCreateDoubleMatrix(1, (size_t)n*(size_t)n, mxREAL);

    T = mxGetPr(plhs[0]);

    sample(n, &T);  
}

此调用返回一个1乘0的空矩阵。因此,它不会分配一个n×n矩阵,也不会填充它。

您有三个非常严重的错误和几个小问题:

  • 此行:
    mwsizen=*(mwSize*)mxGetData(prhs[0])在MEX函数的开头

    这完全没有道理。我们可以清楚地看到,输入是一个整数。实际上,获取一个指向实际数据的指针,该数据作为MEX函数的输入输入,但您正在将指针强制转换为
    mwSize
    ,然后取消对它的引用。我完全不知道这会给你带来什么,但这绝对是不对的。相反,您可以使用指针获取指向数据的实际指针,指针将为您提供符合
    double
    精度实数类型的数据。因为这将是一个整数,所以可以将其转换为
    int

    int n = (int) *mxGetPr(prhs[0]);
    
  • 由于(1)的修正,现在可以分配矩阵,而无需使用
    size\u t
    显式强制转换。我不认为这是一个错误,但更像是一种风格修正:

    plhs[0] = mxCreateDoubleMatrix(1, n*n, mxREAL);
    
  • 这是最重要的错误

    请注意,MEX代码中的
    sample
    函数在内存中接受指向
    double
    指针的指针,以便修改在主MEX网关中创建的矩阵(即
    mexFunction
    )。但是,您首先为要写入输出的矩阵分配内存,但在
    示例
    函数中再次分配内存。因此,实际上您正在创建另一个指向内存的指针,并将数据写入该指针,而不是使用传递给函数的原始指针。具体来说,在
    sample
    中,您有以下代码:

    (*T) = (double*)malloc(n*n*sizeof(double));
    
    因此,退出此功能后,您打算修改的内存未被修改。关键是不需要在函数内部进行分配,因为您已经在函数外部分配了矩阵的内存。这可以从代码中删除

  • 这在内存访问方面非常重要。请记住,MATLAB是一种基于列的主要语言,这意味着矩阵的列是以连续方式排列的,而不是像C这样的语言中的行。因此,如果矩阵的大小为
    m x n
    且有
    m
    行和
    n
    列,则访问矩阵的方法应为
    (*T)[j*m+i]
    ,其中索引
    i
    访问行和
    j
    访问列。现在您将其设置为
    (*T)[i*n+j]
    。现在,由于您的矩阵共享相同的行和列,并且您正在创建一个标识矩阵,因此访问的任何一种方法都是相同的,但请厌倦矩形大小的矩阵

    因此,
    示例
    函数的更正代码如下:

    void sample(int n, double** T)
    {     
        int i, j;
    
        if (*T == NULL)
        {
             return;
        }
    
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                if (i != j)
                    (*T)[j*m + i] = 0;
                else 
                    (*T)[j*m + i] = 1;
            }
        }
    }
    
    如果要创建
    n x n
    矩阵,请将调用更改为
    mxCreateDoubleMatrix
    ,以便将第一个和第二个参数都设置为
    n

    plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL);
    
  • 这不是一个错误,但值得挑剔。您的函数只需要1个输入,因此无需将
    T
    作为第二个参数提交。您的代码不会检查第二个参数。此外,您需要为要编译的代码包含适当的标题:

    #include <stdlib.h> /* For malloc */
    #include "mex.h" /* For the MEX library */
    
    plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL);
    
    #include <stdlib.h> /* For malloc */
    #include "mex.h" /* For the MEX library */
    
    #include <stdlib.h>
    #include "mex.h"
    
    void sample(int n, double** T)
    {     
        int i, j;
        if (*T == NULL)
        {
            return;
        }
    
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                if (i != j)
                    (*T)[j*m + i] = 0;
                else 
                    (*T)[j*m + i] = 1;
             }
        }
    }
    
    void mexFunction( int nlhs, mxArray *plhs[],
                      int nrhs, const mxArray *prhs[] )
    {
        int n = (int) *mxGetPr(prhs[0]);
        double *T;
    
        plhs[0] = mxCreateDoubleMatrix(1, n*n, mxREAL);
        /* Change to this line if you wish to have a n x n matrix */
        /* plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL); */
    
        T = mxGetPr(plhs[0]);
    
        sample(n, &T);  
    }
    
    >> mex -O sample.c
    Building with 'gcc'.
    MEX completed successfully.
    >> n = 5;
    >> T = sample(n)
    
    T =
    
         1     0     0     0     0
         0     1     0     0     0
         0     0     1     0     0
         0     0     0     1     0
         0     0     0     0     1