Ir ao conteúdo
  • Cadastre-se

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


jackson50

Posts recomendados

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;
}

Link para o comentário
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

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...