I managed to succed to work with Variable length Arrays in C and I have now the following:
#include <stdio.h>
#include <stdlib.h>
int (*foo(size_t row, size_t col))[3];
int main(void){
size_t row, col;
printf("Give the ROW: ");
if ( scanf("%zu",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%zu",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
int (*arr)[col] = foo(row, col);
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
printf("%d ",*(*(arr+i)+j));
}
}
free(arr);
}
int (*foo(size_t row, size_t col))[3]{
int (*arr)[col] = malloc(row * col * sizeof(int));
int l=0;
if (arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
*(*(arr+i)+j) = l;
l++;
}
}
return arr;
}
Output:
Give the ROW: 2
Give the COL: 5
0 1 2 3 4 5 6 7 8 9
Now This:
int (*foo(size_t row, size_t col))[3]{ /* code */ }
means, if I understood right that declares foo as a function with two parameters (size_t row, size_t col) that returns a pointer to an array 3 of int.
I'm not entirely capable to understand this kind of Function and it is more complicated for me now working with Variable length Arrays when the size is known only at run time, but I find this a good thing. I am working only with C11 standard.
Any way here int (*foo(size_t row, size_t col))[3] I have this [3] which I'm not clear about how it works and how can I make it possible on run time (of course only if is possible), something like int (*foo(size_t row, size_t col))[SIZE].
I read some books about C, but there is no exactly explanations about this situation and Google doesn't help either, so I have two Questions:
1) Is this posiible int (*foo(size_t row, size_t col))[SIZE] , where SIZE has to be parameter? Or should i declare this Function in another way?
2) is this the right way for what I tried here, or there is another alternative?
I'm only trying to return a pointer to an array where the size is know at run time and not compile time. The call of malloc and free happens only one time and this is a good approach, because whenever malloc is called, our program disturb kernel to allocate memory and mark page as writable.So this method have less over head on kernel.
It can be written in one malloc working with VLA's
EDIT:
@ChronoKitsune said that i should use/try [] (array of unspecified size) in which case the function will become like this:
int (*foo(size_t row, size_t col))[]{ /* code */ }
Is this what i should use?
[](array of unspecified size). 2) Yes, you have the syntax correct. The most equivalent alternative would be to just return a normal pointer. You'd then either declarearrasint *arr = foo(row, col);and use it asarr[i * col + j](or*(arr + i * col + j)), or you'd cast the return value to match the declaration ofarras inint (*arr)[col] = (int (*)[col])foo(row, col);to be able to usearr[i][j](or*(*(arr + i) + j)since you're fond of using pointer notation rather than the more readable equivalent using array notation).int (*arr)[col][]formally denotes an array of incomplete type (C11 section 6.7.6.2p4). Returning a pointer to that array is allowed. However, you can't dereference that pointer until the pointer has been assigned to an array with complete type. For example, if you declaredint (*arr)[] = foo(row, col);then you couldn't do*arrorarr[...]at all.int (*arr)[col] = foo(row, col);is allowed, and you can then successfully use the pointer as desired becauseint (*arr)[col]is a pointer to a complete type.