Problems when deleting the first element from the chained list

Asked

Viewed 61 times

1

Dear friends, for example, I am using a list simply chained, without head and I need to write a function to delete an X element in the list. I made the following code:

#define Limite 21

typedef struct aluno{
    char nome[Limite];
    float nota;
    struct aluno* ponteiro;
}t_aluno;

aluno* cria_aluno(){
    aluno* novo = (aluno*)malloc(sizeof(aluno));
    return novo;
}

\\Insere no inicio
aluno* inserir_aluno(aluno* Lista, char nome[], float nota){
    aluno *novo_aluno = cria_aluno();
    
    strcpy(novo_aluno->nome, nome);
    novo_aluno->nota = nota;
    
    if(Lista == NULL){
        Lista = novo_aluno;
        novo_aluno->ponteiro = NULL;
    }else{
        novo_aluno->ponteiro = Lista;
        Lista = novo_aluno;
    }
    return Lista;
}

void excluir(aluno *Lista, aluno *anterior){    
        aluno* lixo;
        if(anterior != NULL){
            lixo = anterior->ponteiro;
        }else{
            lixo = Lista;
        }
    
        if(lixo == Lista && lixo->ponteiro == NULL){
            Lista = NULL;
        }else if(lixo == Lista && lixo->ponteiro != NULL){
            aluno *prox = lixo->ponteiro;
            printf("%s", prox->nome);
            Lista = lixo->ponteiro; 
        }else{
            anterior->ponteiro = lixo->ponteiro;
        }
        
        free(lixo);
}

aluno *indexPrev(aluno *Lista, char nome[]){
    if(Lista != NULL){
        aluno *i = Lista;
        aluno *prox = NULL;
        
        if(strcmp(nome, i->nome) == 0){
            i = NULL;
            return i;
        }
        
        while(i != NULL){
            prox = i->ponteiro;
            if (strcmp(nome, prox->nome) == 0){
                return i;
            }
            i = i->ponteiro;
        }
    }else{
        printf("Lista vazia \n");
    }
}

int main() {
        int total = 0;
        int v = 0;
        char nome_aluno[Limite];
        float nota = 0;
        t_aluno *Lista = NULL;
        
        while (v != 6){
        
        printf(" \n -------------------------------- \n ESCOLA \n -------------------------------- \n  1 - Cadastrar aluno \n  2 - Ver todos os alunos \n  3 - Ver relacao aprovados x reprovados \n  4 -  \n  5 - Excluir aluno \n 6 - Sair \n -------------------------------- \n");
        
        scanf("%d", &v);
        switch (v) {
        case 1:
            printf("  Insira o nome do aluno: ");
            scanf("%s", &nome_aluno);
            printf("  Insira a nota: ");
            scanf("%f", &nota);
            
            Lista = inserir_aluno(Lista, nome_aluno, nota);
           
            break;
        case 2:
            
            break;
        case 3:
            
            break;
        case 4:
            break;
        case 5:
            char *n;
            
            printf("Informe o nome do aluno: \n");
            scanf("%s", nome_aluno);
            
            //aluno *index = indexOf(Lista, nome_aluno);
            aluno *anterior = indexPrev(Lista, nome_aluno);
            excluir(Lista, anterior);
            break;
        }
    }
}

The "delete" function excludes the element if it is in the middle or at the end of the list. But when it is in the first position, the element is not excluded and the print the list, it returns me a data totally messed up, as the image below:
problema no print

Kindly, I’d like to know where I’m going wrong and what brings this one back " rubbish "?

  • Edit your question and post the input code and the list creation code as well. Your example should be reproducible by anyone who wants to help you. Hug!!

1 answer

1


Boy, your code is pretty messed up but just by the description of the problem I can see what the problem is.

There are 2 possible solutions:

  1. Pass a pointer to the pointer as a parameter to treat the specific case of deleting the first element.

  2. Change the void return type for student*.

The second suggestion is simpler to understand... follows below the amendments I mentioned.

  aluno* excluir(aluno *Lista, aluno *anterior){    // muda o cabeçalho aqui
    aluno* lixo;
    if(anterior != NULL){
        lixo = anterior->ponteiro;
    }else{
        lixo = Lista;
    }

    if(lixo == Lista && lixo->ponteiro == NULL){
        Lista = NULL;
    }else if(lixo == Lista && lixo->ponteiro != NULL){
        aluno *prox = lixo->ponteiro;
        printf("%s", prox->nome);
        Lista = lixo->ponteiro; 
    }else{
        anterior->ponteiro = lixo->ponteiro;
    }
    
    free(lixo);
    return Lista; //adiciona essa linha

}

and when it’s time to call...

Lista = excluir(Lista, anterior);

for the first option would be something like:

 void excluir(aluno **Lista, aluno *anterior){    // alterou aqui
    aluno* lixo;
    if(anterior != NULL){
        lixo = anterior->ponteiro;
    }else{
        lixo = *Lista; //alterou aqui
    }

    if(lixo == *Lista && lixo->ponteiro == NULL){ //alterou aqui
        *Lista = NULL;
    }else if(lixo == *Lista && lixo->ponteiro != NULL){ //alterou aqui
        aluno *prox = lixo->ponteiro;
        printf("%s", prox->nome);
        *Lista = lixo->ponteiro; //alterou aqui
    }else{
        anterior->ponteiro = lixo->ponteiro;
    }
    
    free(lixo);
}

and then calls with:

excluir(&Lista, anterior);

It’s hard to explain with just text... I’ll set an example here for you to see the difference.

#include <stdio.h>
#include <stdlib.h>
void f1(int* pt)
{
   printf("endereco no inicio de f1 = %p\n", pt);
   pt = (int*)malloc(sizeof(int) * 10);
   printf("endereco no final de f1 = %p\n", pt);
}

void f2(int** pt)
{
   printf("endereco do parametro sem derreferenciar %p\n", pt);
   printf("endereco no inicio de f2 = %p\n", *pt);
   *pt = (int*) malloc(sizeof(int) * 10);
   printf("endereco no final de f2 = %p\n", *pt);
}

int main (){
   int *p = (int*) malloc(sizeof(int)* 10);

   printf("O endereco incial de p eh: %p\n", p);
   f1(p);
   printf("O endereco de p depois de f1 eh: %p\n", p);
   f2(&p);
   printf("O endereco de p depois de f2 eh: %p\n", p);
}

Note that the value of p changes if you call F2 but does not change if you call F1...

  • I had already done returning student the problem is that I need, narrowly, to do with the void type. I could not understand the first suggestion, could give an example ?

  • I’ll edit the reply and add at the end

  • managed to understand?

  • Yes I did ! I had not thought that way before and when he spoke up he had not been able to associate. I just have to thank you for taking the time to solve!

Browser other questions tagged

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