Arhama
Arhama

Reputation: 75

How to create a multidimensional array, whose dimension is based on a variable in C?

Basically, I want to be able to type in the dimension n in the terminal and create the corresponding n-D array.

Right now I'm only able to create a one dimensional array with the size of the corresponding n-D array.

Upvotes: 0

Views: 106

Answers (3)

Manny_Mar
Manny_Mar

Reputation: 398

You can set the size of the array at runtime using VLA. Variable-length arrays are part of C99. So this will only work with C99 or up. Although C11 has VLA as an option, all major compilers support it.

Lets say you want the user to input the size of a 2D array from the terminal.

#include <stdio.h>

int main(void)
{
   unsigned int row1, col1;

   printf("%s", "Enter number of rows and columns in a 2-D array: ");
   int row1, col1; // number of rows and columns in a 2-D array
   scanf("%u %u", &row1, &col1);

   int array2D[row1][col1]; // declare 2-D variable-length array

}

array2d is a 2d array declared at run time. Then just write code below to use it.

In early versions of C sizeof was always a compile-time operation, but when applied to a VLA, sizeof operates at runtime. Will print the number of bytes in a VLA:

Upvotes: 1

count0
count0

Reputation: 2621

Use pointers to pointers/double pointers (**). For a n-D array you repeat the process of dynamic allocation (malloc) n times in a loop and reference each with a pointer to newly the allocated array. The only issue is that the last array does not use double pointers, so your runtime code has to know when to use values instead of double-pointers at the last dimension. Using this you can still do setting/getting via conventional syntax like M[1][2][3][1] = 5; (mind that 0 is the first element!).

Also make sure to initialize your values.

For a good example and treatise of double array pointers check 'The C Progamming Language' from Kerningham/Richie, which is readily available online.

Note: there are other elegant and not so elegant solutions to this. For example using macros/metaprogramming to write the allocation code at compile time and pass an define option (-DDIMS=4) or nest-able data structures representing arrays like trees (check classic data structure literature for multi-dim arrays.)

Upvotes: 0

Lefteris Eleftheriades
Lefteris Eleftheriades

Reputation: 331

You can't, the number of dimensions of an array is part of the type, so it needs to be known at compile time. You can do some simple math, to map what you want to a 1d array.

Example:

Let dimensions = 3

  • w: 4
  • h: 8
  • d: 16

Code:

int* data = (int*)malloc(sizeof(int) * w * h * d);
int x = access(1,2,3);  //it will map to location: 1 + 2 * (4) + 3 * (4 * 8)
free(data);


int access(int x, int y, int z){
   return data[x + y * (w) + z * (h * w)];
}

A general implementation might look like this

int numDimensions;
printf("Enter number of dimensions:");
scanf("%d", &numDimensions);
int* dimensionSizes = (int*)malloc(sizeof(int) * numDimensions);

//Read each dimension's size
int totalElements = 1;
for(int i = 0; i < numDimensions; ++i){
    printf("Enter size for dimension %d:", i);
    scanf("%d", &dimensionSizes[i]);
    totalElements *= dimensionSizes[i];
}

//allocate 1d array
int* data = (int*) malloc(sizeof(int) * totalElements);

//Read the coordinates you want to store data to
int* position = (int*)malloc(sizeof(int) * numDimensions);
for(int i = 0; i < numDimensions; ++i){
    printf("Enter location in dimension %d:", i);
    scanf("%d", &position[i]);
}

//Read the value you want to store
int value;
printf("Enter value for that position:");
scanf("%d", &value);

//Write the data to the calculated 1d location
data[to1d(position, dimensionSizes, numDimensions)] = value;

int to1d(int* position, int* dimensionSizes, int numDimensions){
    int multiplier = 1;
    int position1d = 0;
    for (int i = 0; i < numDimensions; ++i){
        position1d = position1d + position[i] * multiplier;
        multiplier = multiplier * dimensionSizes[i];
    }
    return position1d;
}

Upvotes: 2

Related Questions