JShorthouse
JShorthouse

Reputation: 1670

Creating a static global, variable length 2D array

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

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.

Upvotes: 0

Views: 374

Answers (3)

Eric Postpischil
Eric Postpischil

Reputation: 222744

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.

Upvotes: 2

klutt
klutt

Reputation: 31389

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).

Upvotes: 1

dbush
dbush

Reputation: 223927

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));
}

Upvotes: 1

Related Questions