I am trying to build a tic tac toe program for an assignment. My trouble is making a dynamic array, I am new to c and my understanding of pointers and malloc is still very limited. I would like a resource I could read or an explination of how malloc works for a 2d array. This is my code as right now, the malloc section is me trying to understand what I have been able to find on the internet so I know it is incorect.

Program: tic tac toe
Author: charles haselden
Description: Plays tic tac toe either with a NPC or another player
Input: players, x or o
Output: gameboard after every round with positions played.

char check_left(char ply);
char check_right();
char check_diag();
char check_up();
char check_down();
char board (int move, char in);
int is_over();
char who_won();
char board_build();

int main(){
    int players=0;
    char piece, inplay;
    int move_row, move_col;
    int temp =1;
    printf("number of players? ");
    scanf("%i", &players);
        printf("error: incorrect number of players");
        return -1;
    printf("Enter your move row by col\n");
    scanf("%i", &move_row);
    scanf("%i", &move_col);
    inplay = board(temp, inplay);

    return 0;
//char board_build(){
//    int row,col;
//    char build[3][3];
//     for(row=0;row<=2;row++){
//        for(col=0;col<=2;col++){
//            build[row][col]=0;
//        }
//     }
//     return build;
char board(int move, char in){
    int row=3;
    int col=3;
    int *ptr = malloc(sizeof(*ptr));
    char **build;//=malloc(sizeof(**build));

//    build =(int **)malloc(sizeof(int)*row);
//    *build = malloc(sizeof(int)*col);
    //use malloc
    //char build[3][3];

     printf("    c1   c2   c3\n");
     printf("r1  %c  | %c  | %c\n", build[0][0],build[0][1],build[0][2]);
     printf("   ----+----+----\n");
     printf("r2  %c  | %c  | %c\n", build[1][0],build[1][1],build[1][2]);
     printf("   ----+----+----\n");
     printf("r3  %c  | %c  | %c\n", build[2][0],build[2][1],build[2][2]);
    // printf("%s", build);
    return ptr;

char check_left(char ply){

char check_right(){

char check_diag(){

char check_down(){

char check_up(){


This may help. You can find details about dynamic memory for arrays near the bottom, but the rest is useful information about pointers too. :)