Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
357 views
in Technique[技术] by (71.8m points)

c - How can I work with dynamically-allocated arbitrary-dimensional arrays?

The typical 1-D array can be statically or automatically allocated in a declaration.

enum { n=100 };
int arr1[n];

Or dynamically-allocated and accessed via a pointer.

int *arr1m=malloc(n*sizeof*arr1m);
int *arr1c=calloc(n, sizeof*arr1c);

Both of these styles access an element with the same syntax.

int i = n/2;
arr1[i] = arr1c[i] = arr1m[i] = 42;

But when you add a second dimension, it takes some effort to achieve the same syntax.

int arr2[n][n];
int *arr2c=calloc(n*n,sizeof*arr2c);
arr2[5][5] = arr2c[5*n+5] = 23;

You can only get the doubled set of brackets if instead you construct it as an Iliffe-vector.

int **arr2l=calloc(n,sizeof*arr2l);
for (int j=0; j<n; j++)
    arr2l[j]=calloc(n,sizeof**arr2l);
 arr2[6][6] = arr2l[6][6] = 72;

But this becomes more and more cumbersome as the dimensions increase.

Another difficulty is checking the bounds of a dynamic array before accessing an element (so that you're not touching memory that was not properly allocated). The real arrays can use the sizeof operator to determine the bounds, but none of these dynamic arrays carry their size with them.

How can I define a structure that has fast, contiguous layout like an array, but with a consistent syntax for accessing elements with a list of indices that works the same for a 2D array as for a 3D array; and all dynamically, with sizes available dynamically so they can be passed to and returned from functions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There is no need to reinvent the wheel, C has that since C99, it is called variable length array, VLA. It has just the syntax as "normal" d-dimensional arrays, only that the bounds may be variable and they are not allowed in file scope.

As such objects can become relatively large, you should not allocate them on the stack, but with something like malloc

double (*A)[n][m] = malloc(sizeof(double[k][n][m]));

The compiler then helps you with all the index calculations without problems. If you want to pass such animals to functions you just have to be careful to declare the bounds first:

void func(size_t k, size_t n, size_t m, double A[k][n][m]);

This makes your intent clear to both, the human reader and the compiler. I prefer this over the equivalent form

void func(size_t k, size_t n, size_t m, double (*A)[n][m]);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...