Creating a static global, variable length 2D array

2020-06-29 21:38发布

I am trying to create an array with the following requirements:

  • internal linkage (static global)
  • size only known at runtime
  • elements accessed using the [][] syntax
  • stored on the heap

I have been using the following code to create a VLA which meets almost of my requirements, but this array is limited to the current scope rather than having internal linkage.

int (*array_name)[columns] = malloc( sizeof(int[rows][columns]) );

Is there any way to create an array which meets all of my needs?


Edit - "static global" is an incorrect term for this type of variable scope, "internal linkage" is correct. Please look at the comments to this question for an explanation.

3条回答
够拽才男人
2楼-- · 2020-06-29 22:13

You can define the array as follows:

int **array;

And allocate it like this:

array = malloc(rows * sizeof (int *));
for (i=0; i<rows; i++) {
    array[i] = malloc(cols * sizeof(int));
}
查看更多
仙女界的扛把子
3楼-- · 2020-06-29 22:28

The requested properties can be accomplished as described below. (This is not a recommendation to do so.)

Define a base pointer and an array size:

static void *MyArrayPointer;
static size_t Columns;

When the array size is known, initialize them:

Columns = some value;
MyArrayPointer = malloc(Rows * Columns * sizeof(int));
if (!MyArrayPointer) ... Handle error ...

Define a macro to serve as the array:

#define MyArray ((int (*)[Columns]) MyArrayPointer)

Once the above is complete, the array may be accessed as MyArray[i][j].

Note that variable length array support is optional in C. GCC and Clang support them. Given the example shown in the question, we presume variable length array support is available.

Also, I would be tempted to write the malloc code:

MyArrayPointer = malloc(Rows * sizeof *MyArray);

This has the advantage of automatically adjusting the allocation in case the type used in MyArray ever changes.

查看更多
做自己的国王
4楼-- · 2020-06-29 22:33

No, it's not possible to create an array like that. You cannot create VLA:s in global space, because globals are static and static objects needs to have their sizes defined at compile time.

What you can do is to use something like this:

int **arr;

int foo() // Or main, or any function
{
    arr = malloc(sizeof(*arr) * rows);
    for(int i=0; i<rows; i++)
        arr[i] = malloc(sizeof(*arr[0]) * cols);

Of course, rows and cols needs to be declared and initialized and you should also check if the allocation failed. I'm omitting that here.

And yes, you can use []. The bracket operator is just syntactic sugar for pointer aritmetics. a[i] is the same as *(a+i).

查看更多
登录 后发表回答