难以理解meschach库中的数据结构

难以理解meschach库中的数据结构,c,matrix,C,Matrix,我正在阅读矩阵和向量计算库的源代码。以下是库中使用的数据结构: /* matrix definition */ typedef struct { unsigned int m, n; unsigned int max_m, max_n, max_size; Real **me,*base; /* base is base of alloc'd mem */ } MAT; 在这里,*base在结构中有什么用途?我

我正在阅读矩阵和向量计算库的源代码。以下是库中使用的数据结构:

/* matrix definition */
typedef struct  {
        unsigned int    m, n;
        unsigned int    max_m, max_n, max_size;
        Real    **me,*base; /* base is base of alloc'd mem */
        } MAT;
在这里,
*base
在结构中有什么用途?我的意思是,
**me
是一个包含矩阵的矩阵,上面的值包含它的维度,
包含什么

为矩阵分配内存的代码:

MAT *m_get(int m, int n)
{
   MAT  *matrix;
   int  i;
   
   if (m < 0 || n < 0)
     error(E_NEG,"m_get");

   if ((matrix=NEW(MAT)) == (MAT *)NULL )
     error(E_MEM,"m_get");
   else if (mem_info_is_on()) {
      mem_bytes(TYPE_MAT,0,sizeof(MAT));
      mem_numvar(TYPE_MAT,1);
   }
   
   matrix->m = m;       matrix->n = matrix->max_n = n;
   matrix->max_m = m;   matrix->max_size = m*n;
#ifndef SEGMENTED
   if ((matrix->base = NEW_A(m*n,Real)) == (Real *)NULL )
   {
      free(matrix);
      error(E_MEM,"m_get");
   }
   else if (mem_info_is_on()) {
      mem_bytes(TYPE_MAT,0,m*n*sizeof(Real));
   }
#else
   matrix->base = (Real *)NULL;
#endif
   if ((matrix->me = (Real **)calloc(m,sizeof(Real *))) == 
       (Real **)NULL )
   {    free(matrix->base); free(matrix);
    error(E_MEM,"m_get");
     }
   else if (mem_info_is_on()) {
      mem_bytes(TYPE_MAT,0,m*sizeof(Real *));
   }
   
#ifndef SEGMENTED
   /* set up pointers */
   for ( i=0; i<m; i++ )
     matrix->me[i] = &(matrix->base[i*n]);
#else
   for ( i = 0; i < m; i++ )
     if ( (matrix->me[i]=NEW_A(n,Real)) == (Real *)NULL )
       error(E_MEM,"m_get");
     else if (mem_info_is_on()) {
    mem_bytes(TYPE_MAT,0,n*sizeof(Real));
       }
#endif
   
   return (matrix);
}
MAT*m_get(int m,int n)
{
MAT*矩阵;
int i;
if(m<0 | | n<0)
错误(E_NEG,“m_get”);
如果((矩阵=新(MAT))=(MAT*)空)
错误(E_MEM,“m_get”);
else if(mem\u info\u在()上){
mem_字节(TYPE_MAT,0,sizeof(MAT));
mem_numvar(类型1);
}
矩阵->m=m;矩阵->n=矩阵->最大n=n;
矩阵->最大m=m;矩阵->最大尺寸=m*n;
#ifndef分段
如果((矩阵->基=新的(m*n,实数))==(实数*)空值)
{
自由(矩阵);
错误(E_MEM,“m_get”);
}
else if(mem\u info\u在()上){
mem_字节(TYPE_MAT,0,m*n*sizeof(Real));
}
#否则
矩阵->基=(实*)空;
#恩迪夫
如果((矩阵->me=(实数**)calloc(m,sizeof(实数*))==
(实**)空)
{free(矩阵->基);free(矩阵);
错误(E_MEM,“m_get”);
}
else if(mem\u info\u在()上){
mem_字节(TYPE_MAT,0,m*sizeof(Real*));
}
#ifndef分段
/*设置指针*/
对于(i=0;ime[i]=&(矩阵->基[i*n]);
#否则
对于(i=0;i我[i]=新的_A(n,实))==(实*)空)
错误(E_MEM,“m_get”);
else if(mem\u info\u在()上){
mem_字节(TYPE_MAT,0,n*sizeof(Real));
}
#恩迪夫
回报(矩阵);
}
为什么他们首先分配base并使用它分配
me
?另外,如果您已经阅读了源代码,请告诉我这个库中分段的用法。声明在
configure
文件中


矩阵结构在
matrix.h
中定义,m_get()在
memory.c

如果我正确读取了代码,
me
是指向矩阵中“行”开头的指针的一维数组:
matrix->me[I]=&(matrix->base[I*n]);
用索引
i
处相应行的地址填充数组

这使得使用带有两个索引的
me
成为可能,就好像它确实是一个二维数组一样,例如写入
double d=myMatrix.me[row][column];
。当然
sizeof(myMatrix.me)
或获取
me
元素的地址的行为与适当的二维数组不同

如果定义了分段,则矩阵中的内存将逐行分配,并且不连续(并且
将为空)。如果要将原始二维数组传递给不知道
MAT
类型的库,则元素需要在内存中保持连续。如果只是正常索引,则无所谓


顺便说一句(我知道这是一个库中的代码,但仍然):有趣的是,就在今天,Jens Gustedt向我介绍了一个有趣的问题解决方案。他使用C99功能,可变长度数组。有趣的是,他实际上并没有创建任何可变长度数组(相反,他只是像你的matrix类一样使用mallocs)但是只是在声明中使用了运行时长度。非常有趣。他帖子中的
A
在你的矩阵类中扮演了
me
的角色,也就是说,它是一个指向一维数组的指针,可以索引两次以从矩阵中获得一个数字。

如果我正确阅读代码,
me
就是一维数组指向矩阵中“行”开头的指针数组:
matrix->me[i]=&(matrix->base[i*n]);
用索引
i
处相应行的地址填充数组

这使得使用带有两个索引的
me
成为可能,就好像它确实是一个二维数组一样,例如写入
double d=myMatrix.me[row][column];
。当然
sizeof(myMatrix.me)
或获取
me
元素的地址的行为与适当的二维数组不同

如果定义了分段,则矩阵中的内存将逐行分配,并且不连续(并且
将为空)。如果要将原始二维数组传递给不知道
MAT
类型的库,则元素需要在内存中保持连续。如果只是正常索引,则无所谓


顺便说一句(我知道这是一个库中的代码,但仍然):有趣的是,就在今天,Jens Gustedt向我介绍了一个有趣的问题解决方案。他使用C99功能,可变长度数组。有趣的是,他实际上并没有创建任何可变长度数组(相反,他只是像你的matrix类一样使用mallocs)但是只是在声明中使用了运行时长度。非常有趣。他帖子中的
A
在你的矩阵类中扮演了
me
的角色,也就是说,它是一个指向一维数组的指针,可以对数组进行两次索引以从矩阵中获得一个数字。

这个新的A宏定义为什么?#定义新的A(num,type)((type*)calloc((size_t)(num),sizeof(type)))新的A宏定义为什么?#定义新的A(num,type)((type*)calloc((size_t)(num),sizeof(type)))技巧是它看起来像一个,但完全是一维的。仔细检查这个表达式
&(matrix->base[i*n])
:它是一个单一的地址值,如果你想的话是一个数字,它被分配给
me
的一个元素(使用一个索引)。这是真的:在这个地址定义的内存位置上,又有一个完整的(一维)实数数组,即矩阵的一行。在
me[行]中索引
me
生成该行,因此我们可以对第一个索引的结果应用索引,以获得该行的一个元素,如中所示