如何将内存重新分配(例如添加一行)到GSL矩阵?

时间:2016-04-21 15:44:09

标签: c memory-management gsl

如果我有一个已经分配了内存的GSL矩阵,有一种简单的方法可以重新分配该内存,例如添加另一行吗?

我能想到的两种方式是:

size_t n = 2;
gsl_matrix invV = gsl_matrix_alloc(n, n);
// do something with matrix
...
// try and add another row (of length n) by reallocating data in the structure
invV->data = realloc(invV->data, sizeof(double)*(n*n + n));
invV->size1++;

或(使用矩阵视图):

size_t n = 2;
double *invV = malloc(sizeof(double)*n*n)
gsl_matrix_view invVview = gsl_matrix_view_array(invV, n, n);
// do something with &invVview.matrix
...
// try adding another row or length n
invV = realloc(invV, invV->data, sizeof(double)*(n*n + n));
invView = gsl_matrix_view_array(invV, n+1, n);

由于未更改tda structure中的blockgsl_matrix值,我不知道第一种方法是否存在问题。有谁知道这是不是一个问题?

第二种方法运行正常,但是必须在double数组和矩阵视图之间来回切换。

欢迎其他建议。

更新

我有一个简单的测试代码,使用我的第一个选项版本(称为testgsl.c):

#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_matrix.h>

gsl_matrix *matrix_add_row( gsl_matrix *m);

gsl_matrix *matrix_add_row( gsl_matrix *m ){
  if ( !m ){
    fprintf(stderr, "gsl_matrix must have already been initialised before adding new rows" );
    return NULL;
  }  

  size_t n = m->tda; /* current number of columns in matrix */

  /* reallocate the memory of the block */
  m->block->data = (double *)realloc(m->block->data, sizeof(double)*(m->block->size + n));
  if( !m->block->data ){
    fprintf(stderr, "Could not reallocate memory for gsl_matrix!");
    exit(1);
  }
  m->block->size += n;      /* update block size (number of elements) */
  m->size1++;               /* update number of rows */
  m->data = m->block->data; /* point data to block->data */
  return m;
}

int main( int argc, char **argv){
  size_t nrows = 4;
  size_t ncols = 1000;
  gsl_matrix *invV = gsl_matrix_alloc(nrows, ncols);

  //gsl_matrix *testmatrix = gsl_matrix_alloc(1000, 4000);

  /* set to zeros */
  gsl_matrix_set_zero( invV );

  /* try adding a row */
  invV = matrix_add_row( invV );

  fprintf(stderr, "nrows = %zu, ncols = %zu\n", invV->size1, invV->size2);

  /* set some values */
  gsl_matrix_set_zero( invV );
  gsl_matrix_set( invV, 4, 0, 2.3 );
  gsl_matrix_set( invV, 4, 1, 1.2 );

  gsl_matrix_free( invV );
  //gsl_matrix_free( testmatrix );

  return 0;
}

这似乎工作正常(虽然我认为可能会出现一些潜在的内存分配问题)。

1 个答案:

答案 0 :(得分:0)

<{>} Brian Goughgsl_matrix代码的作者之一,似乎suggest我的第二个选项 - 重新分配数组,并在必要时使用向量/矩阵视图