如果我有一个已经分配了内存的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中的block
和gsl_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;
}
这似乎工作正常(虽然我认为可能会出现一些潜在的内存分配问题)。