I have to implement a function for a project in one of my classes and I am having trouble with resizing the dimensions of a 2-D dynamic array, represented as a board of characters. If I resize a board of a size such as 10 X 10 to a smaller board such as 5 X 5, the resize seems to work properly and truncates the arrays accordingly. However, if I try to increase the size of the board I get strange results or segmentation faults, I'm assuming because realloc somehow failed. Any feedback at all would be helpful; I am trying my best to understand pointers and can't seem to wrap my head around how to accomplish this without memory errors. In the larger program that I am writing I have a function to free the allocated memory of the board, but here I am mainly concerned about the way I have implemented realloc.
#include <stdio.h>
#include <stdlib.h>
char** constructBoard(int num_rows, int num_cols, char empty_space){
//this function dynamically allocates a matrix of chars
  char** board = (char**)malloc(num_rows * sizeof(char*));
  for(int row = 0; row < num_rows; ++row){
    board[row] = (char*)malloc(num_cols * sizeof(char));
    for(int col = 0; col < num_cols; ++col){
      board[row][col] = empty_space;
    }
  }
  return board;
}
void displayBoard(char** board, const int num_rows, const int num_cols){
//this function prints out the board
  int rowNum = num_rows - 1;
  for(int row = 0; row < num_rows; ++row){
    if(num_rows - row <= 10) {
      printf(" ");
      printf("%d ", rowNum);
    }
    else{
      printf("%d ", rowNum);
    }
    rowNum = rowNum - 1;
    for(int col = 0; col < num_cols; ++col){
      printf(" %c", board[row][col]);
      printf(" ");
    }
    printf("\n");
  }
  printf("  ");
  for(int i = 0; i < num_cols; ++i){
    if(i == 0){
      printf("  %d", i);
      printf(" ");
    }
    else if(i < 10) {
      printf(" %d", i);
      printf(" ");
    }
    else{
      printf("%d", i);
      printf(" ");
    }
  }
  printf("\n");
}
void resizeBoard(char*** board, int new_num_row, int new_num_col, int* num_rows, int* num_cols){
//this function is supposed to resize the dimensions of the board without causing memory leaks
  (*board) = realloc(*board, (new_num_row * sizeof(char*)));
  for(int y = *num_rows; y < new_num_row; ++y){
    (**board)[y] = '*';
  }
  for(int x = 0; x < new_num_row; ++x){
    (*board)[x] = realloc((*board)[x], new_num_col * sizeof(char));
  }
  *num_rows = new_num_row;
  *num_cols = new_num_col;
}
int main() {
  char empty_space = '*';
  int num_rows = 5;
  int num_cols = 5;
  char** board;
  int new_num_row = 7;
  int new_num_col = 7;
  board = constructBoard(num_rows, num_cols, empty_space);
  displayBoard(board, num_rows, num_cols);
  resizeBoard(&board, new_num_row, new_num_col, &num_rows, &num_cols);
  return 0;
}
 
    