Ir ao conteúdo
  • Cadastre-se
jackson50

Codigo de remover um elemento da lista ordenada em c com erro

Recommended Posts

estou começando a ver e a ter o primeiro contado com lista agora e por isso estou tendo uma certa dificuldade de compreensão da matéria, o professor deixou essa função que remover um elemento da lista para que encontremos o erro, só que to quebrando a cabeça e não conseguir compreender ainda, se alguém poder me ajudar, ficarei grato


Lista *Pop(Lista* l, char valor [])
{
No* aux=l->inicio;
if(listaVazia(l))
{
printf("a pilha esta vazia");
return l;
}
else
{

if(strcmp(valor,aux->dado)==0)
{
free(aux);
l->inicio =NULL;
return l;
}

while(aux->prox!=NULL)
{
No* aux2=aux->prox;
aux->prox=aux2->prox;
free(aux2);
return l;
}
else if(strcmp(valor,aux->prox->dado)<0)
{
printf ("elemento nao existe");
return l;
}
else aux=aux->prox;
}
printf("elemento nao existe");
return l;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vamos "SUPOR" que "aux->prox" seja "igual a nulo" em determinado momento em seu código, dado esse cenário imagine o que isso pode acarretar. Uma possível situação como essa pode acontecer caso você tenha 1 ELEMENTO na lista, ai ela não vai cair no seu primeiro if de lista vazia . . . Mas o próximo elemento é NULL porque você tem 1 elemento só . . Não que isso vai acontecer mas deixar aquele "else aux=aux->prox;" pode ser arriscado . . . Mas isso seria um caso especial . . .

        while(aux->prox != NULL) // aux->prox == NULL ou seja, não cai   aqui !
{
No* aux2=aux->prox;
aux->prox=aux2->prox;
free(aux2);
return l;
}
// Agora perceba, se ele é NULL como você vai acessar o dado dele ?
// Esse else if é desnecessário porque se ele é NULL pra que comparar ?
// Dependendo da situação você pode até invadir memória com essa linha
// Tentando acessar um inteiro não inicializado
else if(strcmp(valor,aux->prox->dado) < 0)
{
printf ("elemento nao existe");
return l;
}

Agora analisando o corpo do while:

        while(aux->prox!=NULL)
{
No* aux2=aux->prox;
aux->prox=aux2->prox;
free(aux2);
return l;
}

Você não tem como fazer looping com esse while porque no final tem um return l . . . Não precisa do while ! Não tem looping, Salvo se essa função esta dentro de outra função recursiva . . . Ai isso pode não ser inútil . . .

No* aux2 = aux->prox; // OK isso tudo bem

aux->prox=aux2->prox; // OK isso tudo bem

free(aux2); // Matou aux2 aqui.

aux2 = aux->prox beleza ! aux2 acessou 1 elemento a frente de aux . . . OK

aux->prox = aux2->prox; Você acessou 2 elementos afrente de aux aqui. Isso é arriscado, porque você não previu que aux->prox->prox é != NULL ! "Dependendo da situação" isso pode estourar memória. Isso não vai estourar a memória com uma lista CHEIA . . . Mas se você tiver 1 elemento só e tentar acessar 2 elementos a frente dele você vai ter um estouro. Ou se você estiver no ultimo da lista e tentar acessar 2 elementos a frente também.

E depois deu free no aux2 . . . Foi meio que inútil ter criado ele . . . Dava pra fazer a mesma coisa só com aux e sem se arriscar desse jeito, prevendo um elemento mais a frente.

Se esse trecho não pegar nenhum caso mencionado a cima ele vai remover 1 elemento depois do aux e fará aux->prox apontar para 2 elementos depois dele.

E sobre essa parte não estou falando da lógica, só dos possíveis erros. Mas se a intenção era remover o primeiro elemento bastava fazer isso:


if(l->primeiro->prox != NULL){
aux = l->primeiro;
l->primeiro = l->primeiro->prox;
free(aux);
return l;
}

E tem mais uma coisa inútil nisso, se você esta passando um ponteiro de lista . . . Pra que retornar a lista :lol: . . .LoL.

Tirando o fato também que entre o if e o else if tem um while LOL . . .

Mas pra te falar a verdade eu não te ajudei em ter falado =P

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×