c – Problem removing at start in a double-threaded list

Question:

Hi. When I try to use the "remove" function to remove the first element from the list, nothing seems to happen. But, right after using the remove function and trying to insert a new node in the list, it doesn't insert, and the second time I try to insert, it returns to insert normally as if nothing had happened. I'm racking my brain with this, and I can't find the problem of why it doesn't remove and it has this "error" when inserting after trying to remove.

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

struct cliente{
    int senha;
    char prio;
    struct cliente *ant,*prox;
};
typedef struct cliente Cliente;

void insere_inicio(Cliente *cabeca);
void listar(Cliente *cabeca);
void libera_lista(Cliente *cabeca);
void retira(Cliente *cabeca);

int main(){

    Cliente *cabeca=(Cliente *) malloc(sizeof(Cliente));
    cabeca->prox = NULL;
    cabeca->ant = NULL;

     int q; /* Caractere para receber a opcao do usuario */
     do {
     printf("\n\nOpcoes:\
     \n1 -> para inserir no inicio o cliente;\
     \n2 -> para listar todas as senhas;\
     \n3 -> para retirar o primeiro da lista;\
     \n0 -> para sair \n:");
     fflush(stdin);
     scanf("%i", &q); /* Le a opcao do usuario */
     switch(q) {
     case 1: insere_inicio(cabeca); break;
     case 2: listar(cabeca); break;
     case 3: retira(cabeca); break;
     case 0: break;
     default: printf("\n\n Opcao nao valida");
     }
     fflush(stdin); /* Limpa o buffer de entrada */
     } while ((q != 0) );
     libera_lista(cabeca);
}

//função para alocar espaço de memoria e criar o nó
/**/
Cliente *aloca(){
    //tenta alocar um novo nó
    Cliente *novono=(Cliente *) malloc(sizeof(Cliente));
    if(!novono){//se não alocou, e portanto novo não existe faça
        printf("Sem memoria disponivel!\n");
        exit(1);
    }else{
         printf("senha: ");
         fflush(stdin);
         scanf("%i", &novono->senha); 
         printf("\nprioridade: [P] para preferencial ou [N] normal: ");
         fflush(stdin);
         scanf("%c", &novono->prio);
         fflush(stdin);
         //q = novono->prio;
         return novono;
    }
}

void insere_inicio(Cliente *cabeca) {

 Cliente *novono=aloca();
 Cliente *aux = cabeca->prox;
 cabeca->prox = novono;
 novono->prox = aux;
 novono->ant = NULL;
}

void listar(Cliente *cabeca){

    if(cabeca->prox == NULL){
        printf("\nTem nada aqui nao hein\n");
        return;
    }   
    Cliente *aux;
    aux = cabeca->prox;
    while(aux != NULL){

        printf("\n\n-------------------------------");
        printf("\nSenha: %i", aux->senha);
        printf("\nPrioridade: %c", aux->prio);
        aux=aux->prox;  
    }
}

void retira(Cliente *cabeca){

    if(cabeca->prox == NULL){
        printf("lista esta vazia");
    }else{
        Cliente *aux;
        aux = cabeca;
        cabeca = cabeca->prox;
    //  cabeca->ant = NULL; 
        free(aux);
    }
}

void libera_lista(Cliente *cabeca){
    //se a lista nao estiver vazia
    if(cabeca->prox != NULL){
        /**/
        Cliente *aux;
        aux = cabeca->prox;
        while(cabeca != NULL){
            aux = cabeca;
            cabeca = cabeca->prox;
            free(aux);

        }

        free(cabeca);

    }
}

Answer:

The problem lies in this part:

void retira(Cliente *cabeca){

if(cabeca->prox == NULL){
    printf("lista esta vazia");
}else{
    Cliente *aux;
    aux = cabeca;
    cabeca = cabeca->prox;
//  cabeca->ant = NULL; 
    free(aux);
  }
}

Two errors are found here.

1st The aux pointer starts to point to the variable head, and should point to the element after the head, which in theory is the first element in the list.

2nd The instruction cabeca = cabeca->prox; it does not eliminate the first element from the list, in fact it makes the cabeca pointer point to where it was already pointing. The correct thing is to make the cabeca point to the next one, which in theory would be the second element, which will become the first

With the necessary corrections, the function will look like this:

 void retira(Cliente *cabeca){
     if(cabeca->prox == NULL){
       printf("lista esta vazia");
    }else{
      Cliente *aux;
      aux = cabeca->prox;
      cabeca->prox = cabeca->prox->prox;

      if(cabeca->prox != NULL){
        cabeca->prox->ant = cabeca;
      }

      aux->ant = NULL;
      aux->prox = NULL;
      free(aux);
   }
}
Scroll to Top
AllEscort