2

is there any convenient way to create a matrix without using malloc? This kind of works:

int *arr2d[3];
int arr0[] = { 0 };
int arr1[] = { 0, 1 };
int arr2[] = { 0, 1, 2 };

arr2d[0] = arr0;
arr2d[1] = arr1;
arr2d[2] = arr2;

printf(%d, arr2d[i][j]);

It doesn't allow you to loop through the values easily as you can't get the size of each subarray as you could using sizeof for arr2d[3][3].

sizeof arr2d[i] / sizeof arr2d[i][0]

Is there any better way to do this?

For reference, here is the same kind of question for C++:

C++ 2 dimensional array with variable size rows

Community
  • 1
  • 1
Forss
  • 778
  • 1
  • 4
  • 13

2 Answers2

2

You cannot do that: in this case, sizeof is evaluated statically, and it represents the size of the pointer. If you need to implement a jagged array with different sizes per row, you have two options:

  • When the size can be computed from the row index, e.g. in a "triangular" array like yours (array length is row+1) you do not store anything at all
  • When the size is arbitrary, create a separate array size_t len[rows], and store each length individually.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Using a struct and compound literals can be done on the stack only.

typedef struct
{
    size_t size ;
    int* a ;

} jag_array ;

jag_array m[] = { { 3 , ( int[] ){ 1,2,3 } } , 
                    6 , ( int[] ){ 1,2,3,4,5,6 } ,  
                    4 ,( int[] ){ 1,2,3,4 } } ;

This has limitations. When you copy the struct the arrays themselves are not copied.

Separate functions and macros could help handling this, but it is not that pretty.

2501
  • 25,460
  • 4
  • 47
  • 87
  • What I find troubling about this approach is how the sizes are literal numbers that are not derived from the array literal. This is an invitation to errors by forgetting to modify the size when the array literal is changed. I'd try to avoid that, even though it'll work fine. – cmaster - reinstate monica Oct 26 '14 at 20:45
  • Found in unwieldy to have to write m[i].a[j], is there a way to avoid that? – Forss Oct 26 '14 at 20:50
  • 1
    @Forss Use a function. – 2501 Oct 26 '14 at 20:50
  • Combining this answer with dasblinkenlight and not using a struct feels simpler. `size_t len[] = { 1, 2, 3 }; int *arr2d[] = { (int[]){0}, (int[]){0, 1}, (int[]){0, 1, 2} };` – Forss Oct 26 '14 at 20:55