Error exited, Segmentation fault when adding a second element to my list

Asked

Viewed 31 times

0

This error only occurs when I add a second element to my chained list, I know the problem is in the Else of the inse_contact function but I can’t identify it.

#include <stdio.h>
#include<stdlib.h>
#include <string.h>
typedef struct{
  char Nome[40];
  char Telefone[15];
  char Celular[15];
  char Email[40];
  struct Agenda *Ponteiro_Aponta_Proximo;
}Agenda;
Agenda *cria_agenda(){
  return NULL;
} 
Agenda *insere_contato(Agenda *Ponteiro_Inicio, char Nome_Parametro, char Telefone_Parametro, char Celular_Parametro, char Email_Parametro){
  if(Ponteiro_Inicio == NULL){
    Ponteiro_Inicio = (Agenda *) malloc(sizeof(Agenda));
    Ponteiro_Inicio->Nome[40] = Nome_Parametro;
    Ponteiro_Inicio->Telefone[15] = Telefone_Parametro;
    Ponteiro_Inicio->Celular[15] = Celular_Parametro;
    Ponteiro_Inicio->Email[40] = Email_Parametro;
    Ponteiro_Inicio ->Ponteiro_Aponta_Proximo = NULL;
    return Ponteiro_Inicio;
  }else{
    Agenda *Vetor_Apontador;
    Vetor_Apontador = (Agenda *) malloc(sizeof(Agenda));
    strcpy(Vetor_Apontador->Nome[40],Nome_Parametro);
    strcpy(Vetor_Apontador->Telefone[15],Telefone_Parametro);
    strcpy(Vetor_Apontador->Celular[15],Celular_Parametro);
    strcpy(Vetor_Apontador->Email[40],Email_Parametro);
    Vetor_Apontador -> Ponteiro_Aponta_Proximo = Ponteiro_Inicio;
    return Vetor_Apontador;

  }
}
void lista_contatos(Agenda *Elementos){
    Agenda *Ponteiro_Para_Impressao = Elementos;
    while(Ponteiro_Para_Impressao != NULL){
    printf("\nO nome do contato é : %s", Ponteiro_Para_Impressao->Nome);
    Ponteiro_Para_Impressao = Ponteiro_Para_Impressao -> Ponteiro_Aponta_Proximo;
  }
}
int main(){
  Agenda * Agnd;
  char Nome_Main[40];
  char Telefone_Main[15];
  char Celular_Main[15];
  char Email_Main[40];
  Agnd = cria_agenda();
  int Opcao = 10;
  while(Opcao != 4){
  printf("\nMenu de opcoes:\n\n");
printf("1 - Inserir Contato\n");
printf("2 - Listar Contatos\n");
printf("3 - Buscar Contato\n");
printf("4 - Sair\n");

printf("\nDigite a opcao a ser executada : ");
scanf("%d",&Opcao);
while(Opcao < 1 || Opcao > 4){
  printf("\nOpcao invalida, Digite novamente a opcao : ");
  scanf("%d",&Opcao);
        
}
switch(Opcao){
  case 1:
    setbuf(stdin, NULL);
    printf("\nDigite o Nome, Telefone, Celular, e Email da pessoa nessa sequencia\n");
    fgets(Nome_Main,40,stdin);
    fgets(Telefone_Main,15,stdin);
    fgets(Celular_Main,15,stdin);
    fgets(Email_Main,15,stdin);
    Agnd = insere_contato(Agnd, Nome_Main, Telefone_Main, Celular_Main, Email_Main);
    break;
  case 2:
    lista_contatos(Agnd);
    printf("\n");
    break;

    }
  }

  return 0;
}

2 answers

0

Try this if you want your second element to be inserted last:

...
Ponteiro_Inicio->Ponteiro_Aponta_Proximo = Vetor_Apontador;
Vetor_Apontador -> Ponteiro_Aponta_Proximo = NULL;
return Vetor_Apontador;
...
  • It didn’t work out, keep making the same mistake! You made it there and it worked?

0


Good afternoon, I took a closer look at your code and made some changes, and with that I will tell you some points:

-First: You weren’t creating a list, you just created a function that returns the value of NULL to a pointer. A List is a pointer to a pointer, meaning a list is an address that points to the first element;

-Second: You were in the first element allocating the list and returning it, and the Pointer_start element only exists in the function while you allocate the first element, then it becomes Agen, then in the second allocation the program no longer knows who is Pointer_start, I mean, you don’t know who to point to, so Sergmentation foult;

-Third: One more tip, try to better organize your program by creating smaller functions, for example, you could create the add_function first, just to add the first element, and the add_element function to add the other elements;

-Fourth: When you are implementing a data structure, leave to implement your program later, in this case, you implemented the list first, then when it was working you implemented the agenda. You can create the struct with any variable, just for the forehead, and the pointer to the next, then when you finished the ED you changed and implemented your agenda. So it becomes much simpler and practical to test the ED.

Follow the code, it is no longer giving foult Segmentation, but this with a string handling warnings:

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

typedef struct{
  char Nome[40];
  char Telefone[15];
  char Celular[15];
  char Email[40];
  struct Agenda *Ponteiro_Aponta_Proximo;
}Agenda;

typedef struct Agenda * Lista;

//Cria Lista
Lista* cria_lista(){
  Lista* lis = (Lista*) malloc(sizeof(Lista));
  if(lis != NULL)
    *lis = NULL;
  return lis;
} 

int *insere_contato(Lista *lis, char Nome_Parametro, char Telefone_Parametro, char Celular_Parametro, char Email_Parametro){
    //se a lista apontar pra null vai alocar o primeiro elemento
    if((*lis) == NULL){
    Agenda *Ponteiro_Inicio = (Agenda*) malloc(sizeof(Agenda));
    Ponteiro_Inicio->Nome[40] = Nome_Parametro;
    Ponteiro_Inicio->Telefone[15] = Telefone_Parametro;
    Ponteiro_Inicio->Celular[15] = Celular_Parametro;
    Ponteiro_Inicio->Email[40] = Email_Parametro;
    //O ponteiro desse elemento para o proximo vai apontar pra NULL
    Ponteiro_Inicio ->Ponteiro_Aponta_Proximo = NULL;
    //A lista vai agora apontar para esse elemento
    *lis = Ponteiro_Inicio;
    return 1;
  }else{
    Agenda *Vetor_Apontador;
    Vetor_Apontador = (Agenda*) malloc(sizeof(Agenda));
    strcpy(Vetor_Apontador->Nome[40],Nome_Parametro);
    strcpy(Vetor_Apontador->Telefone[15],Telefone_Parametro);
    strcpy(Vetor_Apontador->Celular[15],Celular_Parametro);
    strcpy(Vetor_Apontador->Email[40],Email_Parametro);
    Vetor_Apontador->Ponteiro_Aponta_Proximo = NULL;
    //criar uma variavel auxiliar para percorrer a lista ate o ultimo elemento
    Agenda *aux = *lis;
    while(aux->Ponteiro_Aponta_Proximo != NULL)
      aux = aux->Ponteiro_Aponta_Proximo;
    //o ponteiro do ultimo elemento vai passar apontar pra esse
    aux->Ponteiro_Aponta_Proximo = Vetor_Apontador;
    return 1;
  }
}

void lista_contatos(Lista *lis){
    Agenda *Ponteiro_Para_Impressao = *lis;
    while(Ponteiro_Para_Impressao != NULL){
      printf("\nO nome do contato é : %s", Ponteiro_Para_Impressao->Nome);
      Ponteiro_Para_Impressao = Ponteiro_Para_Impressao -> Ponteiro_Aponta_Proximo;
  }
}

int main(){
  Lista * lis;
  int x;
  lis = cria_lista();
  char Nome_Main[40];
  char Telefone_Main[15];
  char Celular_Main[15];
  char Email_Main[40];
  int Opcao = 10;
  while(Opcao != 4){
  printf("\nMenu de opcoes:\n\n");
  printf("1 - Inserir Contato\n");
  printf("2 - Listar Contatos\n");
  printf("3 - Buscar Contato\n");
  printf("4 - Sair\n");

  printf("\nDigite a opcao a ser executada : ");
  scanf("%d",&Opcao);
  while(Opcao < 1 || Opcao > 4){
    printf("\nOpcao invalida, Digite novamente a opcao : ");
    scanf("%d",&Opcao);
        
}
switch(Opcao){
  case 1:
    setbuf(stdin, NULL);
    printf("\nDigite o Nome, Telefone, Celular, e Email da pessoa nessa sequencia\n");
    fgets(Nome_Main,40,stdin);
    fgets(Telefone_Main,15,stdin);
    fgets(Celular_Main,15,stdin);
    fgets(Email_Main,15,stdin);
    x = insere_contato(lis, Nome_Main, Telefone_Main, Celular_Main, Email_Main);
    break;
  case 2:
    lista_contatos(lis);
    printf("\n");
    break;

    }
  }

  return 0;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.