Duvida em vetor de ponteiros

Gostaria de ajuda neste exercício. Pois, não estou conseguindo fazer as funções criaCandidato e novoCandidato. Não entendi bem o que é para fazer. Eu consegui fazer, mas de uma outra forma que não atende bem as funções. Ficarei grato se alguém puder me orientar. Valeuu!

  • criaCandidato: a função recebe como parâmetro três cadeia de caracteres
    representando o nome, curso desejado e endereço do candidato. A função recebe
    também uma estrutura do tipo Data contendo a data de nascimento do candidato.
    A função deve alocar dinamicamente uma estrutura do tipo Candidato e
    armazenar nela as informações do candidato recebidas pela função. Lembre-se de
    alocar dinamicamente as cadeias de caracteres da estrutura com o tamanho exato
    necessário para armazenar as informações.

  • novoCandidato: a função recebe como parâmetro um vetor de ponteiros de
    estruturas do tipo Candidato e também o tamanho máximo de candidatos. A
    função deve ler as informações do candidato (nome, curso, endereço e data de
    nascimento) e armazena-las no vetor de candidatos em um registro vazio (igual a
    NULL). Obrigatoriamente você deve utilizar a função criaCandidato para criar
    um novo candidato. Se não existirem mais espaços livres no vetor de candidatos, a
    função deve exibir uma mensagem de erro.

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct data {
      int dia;
      int mes;
      int ano;
    };
    typedef struct data Data;
    
    struct candidato {
      char *nome;
      char *cursoDesejado;
      char *endereco;
      Data nascimento;
    }; 
    typedef struct candidato Candidato;
    
    void inicializa (Candidato **vet, int n){
      for (int i = 0; i < n; i++){
        vet[i] = NULL;
      }
    
    void criaCandidato (char *nome, char *curso, char *endereco, Data nasc){
      }
    
    void novoCandidato (Candidato **vet, int n){
      for (int i = 0; i < n; i++){
        if (vet[i] == NULL){
          //nao sei se é para alocar dinamicamente aqui ou na funcao criaCandidato
      }
    }
    
    void elimina (Candidato **vet, int n){
      for (int i = 0; i < n; i++){
        if (vet[i] != NULL)
           free(vet);
          vet[i] = NULL;
      }
    }
    
    void exibeInscritos (Candidato **vet, int n){
      for (int i = 0; i < n; i++){
        printf("nome: %s\n", vet[i]->nome);
        printf("curso desejado: %s\n", vet[i]->cursoDesejado);
        printf("endereco: %s\n", vet[i]->endereco);
        printf("nascimento: %d/%d/%d\n", vet[i]->nascimento.dia, vet[i]->nascimento.mes, 
    vet[i]->nascimento.ano);
      }
    }
    
    int main (void){
      /* a função principal do programa que permita que o
       usuário cadastre um número indeterminado de candidatos (até que o usuário indique 
       que ele deseja parar de cadastrar candidatos). Em seguida, o programa deve exibir a 
       lista de todos os candidatos inscritos para o vestibular. */
      return 0;
    }

a função criaCandidato deveria ter Candidato* como tipo de retorno. É dentro dela que você aloca memória dinamicamente para um Candidato, preenche os campos (com os dados que vieram por parâmetro) e retorna esse ponteiro.

A função novoCandidato vai ler do usuário as informações de um novo candidato, criar o novo candidato chamando criaCandidato, e salvar esse ponteiro em algum lugar vazio do vetor **vet.

Exemplo:

typedef struct {
  char *primeiro, *ultimo;
} Nome;

Nome* criaNome (char* primeiro, char* ultimo) {
  Nome *nome = malloc(sizeof(Nome));
  nome->primeiro = primeiro;
  nome->ultimo = ultimo;
  return nome;
}

Valeu, cara. Acabei de testar aqui e deu tudo certinho. Muito obrigado!!