我正在尝试使用C99可变长度数组分配一个2d连续数组。像这样:
size_t rows = 5, cols = 5;
double (*array)[cols] = malloc(rows * sizeof *array);
麻烦的是,我想在一个函数中进行分配。我猜测为了这样做,我需要先声明数组,然后将其地址传递给函数。我一直在尝试这样的事情:
#include <stdlib.h>
#include <stdio.h>
void allocate(double *((*grid)[]), size_t cols)
{
size_t rows = 5; // in practice this the result of a computation
double (*array)[cols] = malloc(rows * sizeof *array);
*grid = array;
}
int main ()
{
size_t cols = 5;
double (*grid)[cols]; // note: edited to fix typo (was [])
allocate(&grid, cols);
return 0;
}
我的编译器(GCC 4.7.1)给了我以下警告/错误:
$ gcc -Wall -pedantic -std=c99 2d.c -o 2d
2d.c: In function ‘allocate’:
2d.c:8:5: error: invalid use of array with unspecified bounds
2d.c: In function ‘main’:
2d.c:16:5: warning: passing argument 1 of ‘allocate’ from incompatible pointer type [enabled by default]
2d.c:4:6: note: expected ‘double * (*)[]’ but argument is of type ‘double (**)[]’
我尝试了很多这种事情,但我显然遗漏了一些东西。我想从grid[j][i]
获得一个连续的2d数组,如main
,但是在一个单独的函数中执行分配。我怎么能这样做?
答案 0 :(得分:2)
更改
void allocate(double *((*grid)[]), size_t cols)
// ^grid is pointer to array of `double *` type
到
void allocate(double (**grid)[], size_t cols)
// ^grid is a pointer to pointer to array of `double` type
答案 1 :(得分:2)
你肯定可以返回指针到多维VLA。我不确定是否可以声明具有这种返回类型的函数,但是,为什么不返回void *
呢?
#include <stdlib.h>
#include <stdio.h>
void *allocate(size_t n, size_t k)
{
int (*p)[n] = malloc(k * sizeof *p);
for (size_t i = 0; i < k; i++) {
for (size_t j = 0; j < n; j++) {
p[i][j] = i * j;
}
}
return p;
}
int main(void)
{
size_t n = 3, k = 5;
int (*p)[n] = allocate(n, k);
for (size_t i = 0; i < k; i++) {
for (size_t j = 0; j < n; j++) {
printf("%d ", p[i][j]);
}
printf("\n");
}
free(p);
return 0;
}
答案 2 :(得分:2)
void allocate( size_t cols, double (**arr)[cols] )
{
size_t rows = ...;
*arr = malloc( sizeof **arr * rows );
}
修改强>
完整示例:
#include <stdio.h>
#include <stdlib.h>
size_t get_rows( void )
{
return 5;
}
void allocate( size_t cols, double (**arr)[cols] )
{
size_t rows = get_rows();
*arr = malloc( sizeof **arr * rows );
if ( *arr )
{
for (size_t r = 0; r < rows; r++ )
for (size_t c = 0; c < cols; c++ )
(*arr)[r][c] = r * cols + c;
}
}
int main( void )
{
size_t cols = 5;
double (*arr)[cols] = NULL;
allocate( cols, &arr );
for ( size_t r = 0; r < get_rows(); r++ )
for ( size_t c = 0; c < cols; c++ )
printf( "arr[%zu][%zu] = %.2f\n", r, c, arr[r][c] );
free( arr );
return 0;
}
答案 3 :(得分:0)
如果你想分配一个连续的二维数组(就像C对静态二维数组一样),你的malloc
将会是
element_type *array = malloc(rows * cols * sizeof *array);
要访问数组,您必须自己进行指针运算:
*(array + i*cols + j);
您描述的代码更类似于jagged arrays。
答案 4 :(得分:0)
以下适用于我:
static void
xalloc(int rows, int cols, double (**array)[cols])
{
*array = malloc(rows * sizeof(**array)) ;
double* p = (void*)*array ;
for (int i = 0 ; i < (rows * cols) ; ++i)
p[i] = i ;
} ;
int
main()
{
int rows = 10 ;
int cols = 7 ;
double (*array)[cols] ;
xalloc(rows, cols, &array) ;
for (int r = 0 ; r < rows ; ++r)
{
printf("%3d:", r) ;
for (int c = 0 ; c < cols ; ++c)
printf("%3d:%4.0f", c, array[r][c]) ;
printf("\n") ;
} ;
} ;
我认为这与为阵列使用Variable Modified类型的愿望是一致的。
请注意,我也觉得它太可怕......但是,嘿,并不是每天都能写出像double (*array)[cols]
那样深奥的东西并且侥幸逃脱它。 / p>
答案 5 :(得分:-1)
尝试更改您的代码,如下所示。
void allocate (double ((**grid) []), size_t cols) {
size_t rows = 5;
double (*arr)[] = (double (*)[]) malloc (rows * sizeof (size_t));
*grid = arr;
}
int main () {
size_t cols = 5;
double (*grid)[] = 0;
allocate (&grid, cols);
printf ("%x", (void *)grid); // to show that the memory is being allocated
return 0;
}