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

时间:2016-02-15 17:00:36

标签: c matrix

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

/* 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是包含矩阵的值,而上面的值包含其维度,base包含的内容。

为矩阵分配内存的代码:

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);
}

为什么他们首先分配基数并使用它来分配me?另外,如果您已阅读源代码,请告诉我在此库中使用SEGMENTED。声明在configure文件中。

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

1 个答案:

答案 0 :(得分:2)

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

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

如果定义了 SEGMENTED ,矩阵中的内存将逐行分配,并且不会连续(并且base将为null)。如果要将原始的二维数组传递给不知道MAT类型的库,则元素将需要在内存中连续存在。如果你只是正常索引它并不重要。

顺便说一句(我知道这是来自图书馆的代码,但仍然存在):很有趣,就在今天,我被Jens Gustedt https://stackoverflow.com/a/12805980/3150802引导到这个问题的有趣解决方案。他使用C99功能,可变长度数组。有趣的是,他实际上并没有创建任何可变长度数组(相反,他只是像你的矩阵类一样使用malloc),而只是在声明中使用运行时长度。非常有趣。他的帖子中的A在你的矩阵类中扮演me的角色,即它是指向一维数组的指针,可以将其索引两次以从矩阵中获得单个数字。 / p>