Aviel Ovadiya
Aviel Ovadiya

Reputation: 99

How can I dynamically allocate 2D-array in one allocate C

Can you help me figure out how to allocate a 2D-array in one allocate call?

I tried to do:

int** arr = (int**)malloc(num * num * sizeof(int*));

But its doesn't work.

num is the rows and columns.

Upvotes: 2

Views: 12454

Answers (3)

Felix Guo
Felix Guo

Reputation: 2708

You can allocate a 2D array in one of 2 ways.

1: Array of Pointers to Arrays

This would be:

int rows = 10; 
int cols = 10;
int **array = malloc(rows * sizeof(int*));
for (int i = 0; i < rows; i++) {
    array[i] = malloc(cols * sizeof(int));
}

array will now point to a list of pointers each representing a row, and those pointers would point to the elements in the row. In this case, you can access the nth row and mth column with array[n][m]

2: Single Continuous Block

This is probably the method you wanted, where you could do it all in one allocation. This would require you to store the 2D array in a 1D representation.

int rows = 10; 
int cols = 10;
int *array = malloc(rows * cols * sizeof(int));

You can then store and retrieve the nth row and mth column with an offset: array[(n * cols) + m]

Upvotes: 2

chux
chux

Reputation: 153338

How can i to allocate dynamically array2D in 1 allocate C

Let us start with what is a 2D array:
Example of a 2D array or "array 3 of array 4 of int"

int arr1[3][4];
arr1[0][0] = this;

OP's code declares a pointer to pointer to int, not a 2D array nor a pointer to a 2D array.
BTW, the cast in not needed.

int** arr = (int**)malloc(num * num * sizeof(int*));

Code can allocate memory for a 2D array and return a pointer to that memory. pointer to array 5 of array 6 of int

 int (*arr2)[5][6] = malloc(sizeof *arr2);
 if (arr2 == NULL) return EXIT_FAILURE;
 (*arr2)[0][0] = this;
 return EXIT_SUCCESS;

 // or with Variable Length Arrays in C99 and optionally in C11
 int (*arr3)[num][num] = malloc(sizeof *arr3);
 (*arr3)[0][0] = that;

Alternatively code can allocate memory for a 1D array and return a pointer to that memory. pointer to array 8 of int. Sometimes this is often what one wants with with an "allocate 2D" array, really a pointer to a 1D array

 int (*arr4)[8] = malloc(sizeof *arr4 * 7);
 arr4[0][0] = this;

 // or
 int (*arr5)[num] = malloc(sizeof *arr5 * num);
 arr5[0][0] = that;

Upvotes: 6

Stephan Lechner
Stephan Lechner

Reputation: 35154

Although I thought the meaning of a "2D-array of integers" is unambiguously something like int arr[10][10], searching the web brought up interpretations like "using an array of pointers" or "using a pointer to a pointer" (cf, for example, this post). The remainder of this answer is based on a 2D-array of the form int arr[r][c], where r denotes the number of rows and c the number of columns per row.

If variable length arrays are not supported, then at least c must be a const expression (i.e. known at compile time). r, in contrast, may be defined at runtime as well, such that at least the number of rows is "dynamic". A 2D-array can then be represented as an (probably incomplete) array of one-D-arrays:

#define COLS 3

void printArray(int array[][COLS], int rows) {
    for(int row=0; row<rows; row++) {
        for (int col=0; col<COLS; col++) {
            printf("%d ", array[row][col]);
        }
        printf("\n");
    }
}

int main() {

    typedef int oneD[COLS];

    int rows = 5;
    size_t myArray5RowsSize = rows*sizeof(oneD);
    oneD *myArray5Rows = malloc(myArray5RowsSize);
    memset(myArray5Rows,0,myArray5RowsSize);
    myArray5Rows[0][0] = 0;
    myArray5Rows[1][1] = 1;
    myArray5Rows[2][2] = 2;

    printArray(myArray5Rows, 5);

    return 0;
}

Upvotes: 1

Related Questions