Función que devuelve un puntero a una matriz

Logré tener éxito para trabajar con matrices de longitud variable enC y ahora tengo lo siguiente:

#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;
}

Salida:

Give the ROW: 2
Give the COL: 5
0 1 2 3 4 5 6 7 8 9

Ahora esto:

int (*foo(size_t row, size_t col))[3]{ /* code */ }

significa, si entendí bien que declara foo como una función con dos parámetros (size_t row, size_t col) que devuelve un puntero a una matriz 3 de int.

No soy del todo capaz de entender este tipo de función y ahora me resulta más complicado trabajar con matrices de longitud variable cuando el tamaño solo se conoce en tiempo de ejecución, pero me parece algo bueno. Estoy trabajando solo conC11 estándar.

De cualquier manera aquíint (*foo(size_t row, size_t col))[3] Tengo esto [3] que no tengo claro cómo funciona y cómo puedo hacerlo posible en tiempo de ejecución (por supuesto, solo si es posible), algo así comoint (*foo(size_t row, size_t col))[SIZE].

Leo algunos libros sobreC, pero no hay explicaciones exactas sobre esta situación y Google tampoco ayuda, así que tengo dos preguntas:

1) ¿Es esto posibleint (*foo(size_t row, size_t col))[SIZE] , donde SIZE tiene que ser parámetro? ¿O debería declarar esta función de otra manera?

2) ¿Es esta la forma correcta de lo que probé aquí, o hay otra alternativa?

Solo estoy tratando de devolver un puntero a una matriz donde el tamaño se conoce en tiempo de ejecución y no en tiempo de compilación. La llamada demalloc yfree sucede solo una vez y este es un buen enfoque, porque siempremalloc se llama, nuestro programa perturba el núcleo para asignar memoria y marcar la página como editable. Por lo tanto, este método tiene menos sobrecargakernel. Se puede escribir en unomalloc trabajando con VLA's

EDITAR:

@ChronoKitsune dijo que debería usar / probar[] (matriz de tamaño no especificado) en cuyo caso la función será así:

int (*foo(size_t row, size_t col))[]{ /* code */ }

¿Es esto lo que debería usar?

Respuestas a la pregunta(1)

Su respuesta a la pregunta