在函数内分配2D连续数组

时间:2014-07-10 15:12:02

标签: c

我正在尝试使用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,但是在一个单独的函数中执行分配。我怎么能这样做?

6 个答案:

答案 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;
}