Executando verificação de segurança...
1

Ponteiro para struct | Como inicializar vetor de struct dentro da struct? | C++ | Dúvidas !

Pessoal estou com uma duvida grande, estou estudando estrutura de dados e como consequencia cheguei a parte de ponteiros, ja entendi a questão do conceito de ponteiro, no qual o ponteiro é uma variável que guarda o endereço de memoria de uma outra variável. Ja quando a gente entra na questão da alocação dinamica (malloc, calloc, realloc e free) comecei a me bater com uma coisa em específico. Estou fazendo um programinha de Agenda telefonica, que tem uma "struct AGENDA", que tem parametros como "nome" e um vetor dinamico de outra struct "struct CONTATO" que armazena todos os contatos desejados pelo usuario dinamicamente.
Certo, agora que entendeu um pouco o escopo do programa, a minha dificuldade é a seguinte, como eu inicializo o vetor "struct CONTATO" que está dentro da "struct AGENDA" que foi inicializada dinamicamente?
Abaixo segue o código que fiz até o momento, existem varios erros, mas estou corrigindo a medida que vou percebendo, mas a priore so quero inicializar as estruturas (struct) corretamente e estou me bantendo com a inicialização do vetor de "struct CONTATO" dentro da "struct AGENDA". Caso não tenha entendido algo, comenta aí que tento explicar melhor minha dúvida!
Segue código abaixo

#include <iostream>
#include <string>
using namespace std;

typedef struct contato {
  string nome;
  string telefone;
  string email;
} CONTATO;

typedef struct agenda {
  string nome;
  CONTATO *listaContato;
} AGENDA;

AGENDA *criarAgenda(string);     // RETORNA UM ENDEREÇO DE MEMORIA
void adicionarContato(AGENDA *); // RECEBE ENDEREÇO DE MEMORIA CORRESPONDENTE A
                                 // AGENDA CRIADA COMO PARAMETRO
void editarContato(string);
void excluirContato(string);
void listarContato();

int main() {
  // ADICIONANDO CHARACTERES ESPECIAIS
  setlocale(LC_ALL, "Portuguese");
  // DECLARANDO VARIAVEIS
  string nome;
  AGENDA *ptrAgenda;
  int sairMenu = 0, opcaoMenu;
  // ENTRADA DE DADOS
  cout << "Digite o seu nome: " << endl;
  cin >> nome;
  cout << "\n" << endl;
  ptrAgenda = criarAgenda(nome);
  // MENU
  do {

    cout << "Agenda de " << nome << ": " << endl;
    cout << "\n" << endl;
    cout << "1 - Adicionar Contato " << endl;
    cout << "2 - Listar Contatos " << endl;
    cout << "3 - Excluir Contato " << endl;
    cout << "4 - Fechar Agenda " << endl;
    cin >> opcaoMenu;

    switch (opcaoMenu) {
    case 1:
      adicionarContato(ptrAgenda);
      break;
    case 2:
      // listarContato();
      break;
    case 3:
      // excluirContato("string");
      break;
    case 4:
      sairMenu++;
      break;
    default:
      cout << "Opção invalida, favor tentar novamente! " << endl;
      break;
    }
  } while (sairMenu == 0);

  return 0;
}

// FUNCIONALIDADES

AGENDA *criarAgenda(string nomeUsuario) {

  AGENDA *novaAgenda; 
  novaAgenda = (AGENDA *)malloc(sizeof(AGENDA)); // RESERVANDO ENDEREÇO DE MEMORIA PARA AGENDEA
  
  cout << "Criou ponteiro para agenda - OK " << endl; // SAÍDA DE TEXTO PARA SABER EM QUAL LINHA ESTÁ TRAVANDO O CODIGO
  
  novaAgenda->nome = nomeUsuario;
  cout << "Adicionou o nome de usuario, sendo ele - OK " << novaAgenda->nome << endl;
  novaAgenda->listaContato = (CONTATO *)malloc(sizeof(CONTATO));
  novaAgenda->listaContato->nome = "NULL";
  novaAgenda->listaContato->telefone = "NULL";
  novaAgenda->listaContato->email = "NULL";

  cout << "Criou lista contato de boa aparentemente, nome: " << endl;
  return novaAgenda;
};

void adicionarContato(AGENDA *agenda) {
  // ENTRADA
  string nomeContato, telContato, emailContato;
  cout << "Digite o nome do contato: " << endl;
  cin >> nomeContato;
  cout << "Digite o telefone do contato: " << endl;
  cin >> telContato;
  cout << "Digite o email do contato: " << endl;
  cin >> emailContato;
  // PROCESSAMENTO
  int tamContato =
      (int)(sizeof(agenda[0].listaContato)) /
      (int)(sizeof(agenda[0].listaContato[0])); // descobrindo tamanho da array
  cout << "tamanho array: " << tamContato << endl;
  agenda[0].listaContato[tamContato].nome = nomeContato;
  agenda[0].listaContato[tamContato].telefone = telContato;
  agenda[0].listaContato[tamContato].email = emailContato;
};
Carregando publicação patrocinada...
0

Apesar do meu post não ter alcançado muita gente, encontrei a resposta, consecutivamente vim trazer pra vocês, caso haja alguem com a mesma dúvida.
Ao estudar a materia de LP na faculdade o professor estava passando todas as estruturas de dados em C, eu quis implementar alguns conceitos de C em C++, isso tava acarretando em diversos erros de compilação que teoricamente não deveriam acontecer. Alterei todo o codigo conforme percebi e ja consegui desenvolver duas funcionalidade, a função "adicionarContato()" e a função "listarContatos()", porem estou agora pensando como resolver a questão dos vetores alocados dinamicamente, consigo adicionar um item, mas ele sobre escreve inves de adicionar mais um espaço de memoria, estou corrigindo o codigo mas ainda há varios erros de logica e sintaxe, mas é justamente por isso que estou trazendo aqui, segue o código abaixo:

Obs.: Estou pensando em usar a estrutura de Pilha para criar a lista de contatos. Mas ja me disseram que pra esse caso Lista é melhor, caso tenha alguma dica, favor comentar abaixo!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct contato {
  char nome[30];
  char telefone[30];
  char email[30];
  struct contato *primeiro;
  struct contato *ultimo;
} CONTATO;

typedef struct agenda {
  char nome[30];
  CONTATO *listaContato;
} AGENDA;

AGENDA *criarAgenda(char[30]);

void adicionarContato(AGENDA *);

void listarContato(AGENDA *);

int main() {

  // DECLARANDO VARIAVEIS
  char nome[30];
  AGENDA *ptrAgenda;
  int sairMenu = 0;
  int opcaoMenu;

  // ENTRADA DE DADOS
  printf("Digite um nome \n");
  fgets(nome, 30, stdin);
  strtok(nome, "\n");

  // PROCESSAMENTO
  ptrAgenda = criarAgenda(nome);

  if (ptrAgenda == NULL) {
    printf("Erro ao alocar a agenda");
  } else {
    // MENU
    do {
      printf("Bem vindo - %s \n\n", ptrAgenda->nome);
      printf("1 - Adicionar Contato \n");
      printf("2 - Listar Contatos \n");
      printf("3 - Excluir Contato \n");
      printf("4 - Fechar Agenda \n");
      scanf("%d", &opcaoMenu);
      printf("\n A escolha do menu foi: %d \n\n", opcaoMenu);
      switch (opcaoMenu) {
      case 1:
        adicionarContato(ptrAgenda);
        break;
      case 2:
        listarContato(ptrAgenda);
        break;
      case 3:
        // excluirContato("string");
        printf("Excluiu o Contato! \n");
        break;
      case 4:
        sairMenu++;
        break;
      default:
        printf("Opção invalida, favor tentar novamente! \n");
        break;
      }
    } while (sairMenu == 0);
  }
  return 0;
}

AGENDA *criarAgenda(char nome[30]) {
  AGENDA *novaAgenda;
  novaAgenda = (AGENDA *)malloc(sizeof(AGENDA));
  strcpy(novaAgenda->nome, nome);
  novaAgenda->listaContato = (CONTATO *)malloc(sizeof(CONTATO));
  int tamContatos = (int)sizeof(novaAgenda[0].listaContato) /
                    (int)sizeof(novaAgenda[0].listaContato[0]);
  return novaAgenda;
};

void adicionarContato(AGENDA *agenda) {
  // DECLARANDO VARIAVEIS
  char nomeContato[30], telContato[30], emailContato[30];
  // ENTRADA DE DADOS
  printf("Digite o nome do novo Contato! \n");
  scanf("%29s", nomeContato);
  printf("Digite o telefone do novo Contato! \n");
  scanf("%29s", telContato);
  printf("Digite o email do novo Contato! \n");
  scanf("%29s", emailContato);
  // PROCESSAMENTO
  int tamListaContatos =
      (int)sizeof(agenda[0].listaContato) /
      (int)sizeof(agenda[0].listaContato[0]); // VERIFICANDO TAMANHO DA LISTA

  if (agenda[0].listaContato[0].primeiro == NULL) {
    // VERIFICA SE JA FOI CADASTRADO ALGUM CONTATO NA AGENDA
    strcpy(agenda[0].listaContato[0].nome, nomeContato);
    strcpy(agenda[0].listaContato[0].telefone, telContato);
    strcpy(agenda[0].listaContato[0].email, emailContato);
    agenda[0].listaContato[0].primeiro = &agenda[0].listaContato[0];
    agenda[0].listaContato[0].ultimo = &agenda[0].listaContato[0];
    printf("Contato adicionado com sucesso! \n");
  } else {
    // CASO JA TENHA ALGUM CONTATO ELE UTILIZA O REALOC
    printf("\n\nCAIU NO REALLOC\n\n");
    agenda[0].listaContato = (CONTATO *)realloc( agenda[0].listaContato, 1 + sizeof(agenda[0].listaContato[0]));
    int tamListaContatos = (int) sizeof(agenda[0].listaContato) / (int)1 + (sizeof(agenda[0].listaContato[0]));
    printf("\n\n%d\n\n", tamListaContatos);

    strcpy(agenda[0].listaContato[tamListaContatos].nome, nomeContato);
    strcpy(agenda[0].listaContato[tamListaContatos].telefone, telContato);
    strcpy(agenda[0].listaContato[tamListaContatos].email, emailContato);
    printf("Contato adicionado com sucesso! \n");
  }
}

void listarContato(AGENDA *agenda) {
  int tamListaContatos =
      (int)sizeof(agenda[0].listaContato) / (int)sizeof(CONTATO);
  for (int i = 0; i <= tamListaContatos; i++) {
    printf("Contato id: %d \n", i);
    printf("Contato nome: %s \n", agenda[0].listaContato[i].nome);
    printf("Contato telefone: %s \n", agenda[0].listaContato[i].telefone);
    printf("Contato email: %s \n", agenda[0].listaContato[i].email);
  }
};