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&nbsp;estándar.

De cualquier manera aquíint (*foo(size_t row, size_t col))[3]&nbsp;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]&nbsp;, 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&nbsp;yfree&nbsp;sucede solo una vez y este es un buen enfoque, porque siempremalloc&nbsp;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&nbsp;trabajando con VLA's

EDITAR:

@ChronoKitsune dijo que debería usar / probar[]&nbsp;(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?