While in general there are many different ways to handle 2D array, the simple answer is no. There is a lot of info about 2d arrays in C: 1, 2, 3, etc. In principle, when dealing with 2d arrays, every dimension except first to the left needs to be specified exactly. In your case, every rectangle is defined by 4 integers, so instead int** rects
consider int*[4] rects
. This makes rectsColSize
useless, because now each column has constant size of 4 ints.
Just for completness: what you are trying to do is second approach to arrays, where each column has independent size, and (usually) additional malloc call. While this approach is also valid and requires int**
type, it is not needed for your task. Nice description of the difference here.
Edit
Here is how to loop through 2d
arrays:
#define col 4
void print_2d(int (*a)[col], int aSize){
for(size_t i = 0; i < aSize; i++){
for(size_t j = 0; j < col; j++){
printf("%d ", a[i][j]);
}
printf("\n");
}
}
and here for int**
:
void print_pp(int** a, int aSize, int* aiSize){
for(size_t i = 0; i < aSize; i++){
for(size_t j = 0; j < aiSize[i]; j++){
printf("%d ", a[i][j]);
}
printf("\n");
}
}
It seems that you want to convert int*[4]
to int**
, or more precisely, int*[4] arr2d
with it's size int arr2dSize
to structure Solution
. In that case, here is wrapper to solutionCreate
.
Solution* solutionCreateWrap(int (*arr2d)[4], int arr2dSize) {
int* rectsColSize = malloc(arr2dSize * sizeof(int));
int** rects = malloc(arr2dSize * sizeof(int*));
size_t arr2dMem = arr2dSize * 4 * sizeof(int);
rects[0] = malloc(arr2dMem);
memcpy(rects[0], arr2d, arr2dMem);
rectsColSize[0] = 4;
for(size_t i = 1; i < arr2dSize; i++){
rects[i] = rects[0] + i*4;
rectsColSize[i] = 4;
}
sol->rects = rects;
sol->rectsSize = rectsSize;
sol->rectsColSize = rectsColSize;
//some codes
}
return solutionCreate(rects, arr2dSize, rectsColSize);
}
Now for int rects[2][4] = {{1, 1, 5, 5}, {6, 6, 9, 9}};
call solutionCreateWrap(rects, 2)
will return initialised structure Solution
. It looks gruesome, and it's details are even worse, so if it just works, you may skip the explanation. Understanding low level C details isn't neccesarily to write in it, and this (or any other) explanation cannot possibly cover this matter, so don't be discouraged, if you won't get it all.
arr2d
is contiguous block of memory of arr2dSize*4
integers. When multiplied by sizeof(int)
we get size in bytes - arr2dMem
in my code. Declaration int (*arr2d)[4]
means, that arr2d
is of type int*[4]
. Knowing this we can cast it to int*
like so: int* arr = (int*)arr2d
and expression arr2d[i][j]
is translated as arr[i*4+j]
.
The translation to rects
is as follows; int**
is array of pointers, so every rect[i]
has to be pointer to i-th row of arr2d
. Knowing this, everything else is pointer arithmetic. rects[0] = malloc(arr2dMem);
and memcpy(rects[0], arr2d, arr2dMem);
copies whole arr2d
to rect[0]
, then every next rects[i] = rects[0] + i*4;
is shifted 4 integers forward. Because rect
is of type int**
, the expression rects[i][j]
translates to *(rects[i]+j)
, and replacing rects[i]
by rects[0] + i*4
, we get *((rects[0] + 4*i)+j)
, that is rects[0][4*i+j]
. Note striking similarity between last expression, and arr[i*4+j]
. rectsColSize
is somewhat superfluous in this case, but it is essential in general int**
array, when every subarray could have different sizes. After wrap function is done, rects
is exact copy of arr2d
, but with type appropriate for your Solution
structure, so we can call solutionCreate()
.