Dynamic Multi-dimensional Arrays

About

Let's make a 2D array with the number of rows and columns unknown at compile time.

We'll first create methods(functions for struct) and push the rows and cols to stack area.

And then in the init function newMyArray, we'll use malloc from stdlib to allocate space for arr in MyArray and the pointer to MyArray itself, and return the pointer.

After printing its content, we'll free the memory with free from stdlib.

Note

Note that:

  • struct's must appear before they're used.

  • You can access the content that's pointed by elements in structs and unions using arrow operator ->.

  • Always free memory after dealing with the memory allocated using malloc.

  • The idiomatic way to create methods for a struct in C is, just passing the struct or the pointer to it to the function that needs the struct.

Example

#include <stdio.h>
#include <stdlib.h>

struct MyArray {
    int** arr;
    int rows;
    int cols;
};

struct MyArray* newMyArray(int rows, int cols) {
    int** arr = malloc(rows * sizeof(*arr));
    for (int i = 0; i < rows; ++i) {
        arr[i] = malloc(rows * sizeof(arr[0]));
    }
    
    struct MyArray* myArr = malloc(sizeof(struct MyArray));
    if (!myArr) {
        perror("malloc failed");
        exit(1);
    }
    
    myArr->arr = arr;
    myArr->rows = rows;
    myArr->cols = cols;
    
    return myArr;
}

void freeMyArray(struct MyArray* myArr) {
    for (int i = 0; i < myArr->rows; ++i) {
        free(myArr->arr[i]);
    }
    free(myArr->arr);
    myArr->rows = 0;
    myArr->cols = 0;
}

void prettyPrint(struct MyArray* myArr) {
    for (int i = 0; i < myArr->rows; i++) {
        for (int j = 0; j < myArr->cols; j++) {
            printf("%d ", myArr->arr[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int ROWS = 2;
    int COLS = 3;
    
    struct MyArray* myArr = newMyArray(ROWS, COLS);
    
    int count = 0;
    for (int i = 0; i < myArr->rows; i++) {
        for (int j = 0; j < myArr->cols; j++) {
            myArr->arr[i][j] = ++count;
        }
    }
    
    prettyPrint(myArr);
    
    freeMyArray(myArr);
}
Output:
1 2 3
4 5 6

References

Last updated