Tomáš Zato Tomáš Zato - 5 days ago 5
C Question

How to create variable length array on heap?

I used C's variable length array to implement an algorithm:

int matrix[rows][cols];


I managed to test that this does fail for ridiculous dimensions. Is there a way to allocate this matrix on heap instead of stack? Otherwise I'll have to rewrite this to
int**
...

Something like
calloc(sizeof(int[rows][cols]), 1)
? Note that this question is specifically about variable length arrays.

Answer

It looks simple enough. The only remotely tricky bit is the type to hold the pointer to the dynamically allocated array:

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

static void print_matrix(int r, int c, int matrix[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            printf(" %d", matrix[i][j]);
        putchar('\n');
    }
}

static void set_matrix(int r, int c, int matrix[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            matrix[i][j] = (i+1) * 100 + j + 1;
    }
}

int main(void)
{
    size_t rows = 9;
    size_t cols = 7;
    size_t size = sizeof(int[rows][cols]);
    printf("rows = %zu, cols = %zu, size = %zu\n", rows, cols, size);
    int (*matrix)[cols] = calloc(sizeof(int[rows][cols]), 1);
    if (matrix != 0)
    {
        set_matrix(rows, cols, matrix);
        print_matrix(rows, cols, matrix);
        free(matrix);
    }
    return 0;
}

This code carefully uses calloc() to zero all the elements of the array, and then calls set_matrix() to set them to non-zero values. As written, malloc() would be better than calloc(), but the question used calloc() and it would not be hard to make it sensible for use with this code too (for example, a conditional assignment in set_matrix(), such as if (i && j && i != j)).

Example output:

rows = 9, cols = 7, size = 252
 101 102 103 104 105 106 107
 201 202 203 204 205 206 207
 301 302 303 304 305 306 307
 401 402 403 404 405 406 407
 501 502 503 504 505 506 507
 601 602 603 604 605 606 607
 701 702 703 704 705 706 707
 801 802 803 804 805 806 807
 901 902 903 904 905 906 907
Comments