Segmentation Fault when removing list occurrences

Asked

Viewed 65 times

2

The following code aims to remove all occurrences of an integer in a list, (linked lists), returning at the end, the number of elements removed.
Give me the error of Segmentation fault. I appreciate any explanation.

typedef struct lligada {
    int valor;
    struct lligada *prox;
} *LInt;

int removeAll (LInt *l, int x){
    int r = 0;
    LInt pt = *l, ant = NULL;
    while (pt != NULL){
        if (pt -> valor == x){
            ant -> prox = pt -> prox;
            pt = pt -> prox;
            r++;
        }
        else {
            ant  = pt;
            pt = pt -> prox;
        }
    }

    return r;
}
  • The chained list of struct lligada items, when removing an instance of lligada struct, must pass the address of that instance to free () otherwise, the result is a memory leak

  • Lint pt = *; >>> Llint pt = *l;

2 answers

2


You have 2 problems with your code:

  • You’re not doing free of the nodes that are removed, and so has a memory leak. This problem despite not being notorious because it does not soon launches a Segmentation fault, ends up leaving its program incorrect, and in a case where it is used excessively and will probably continue.

  • Are you accessing the ant without guarantee that it has been awarded:

    LInt pt = *l, ant = NULL; //ant null aqui
    while (pt != NULL){
        if (pt -> valor == x){
            ant -> prox = pt -> prox; //utilizado aqui
    

    Note that if the first node is to be removed, then the ant is still the NULL for there is no element before that. This causes ant->prox give at once Segmentation fault, as can not dereference null/0.

To fix both problems could rewrite your removeAll for:

int removeAll (LInt *l, int x){
    int r = 0;
    LInt pt = *l, ant = NULL;
    while (pt != NULL){
        if (pt -> valor == x){
            if (ant == NULL){ //se é o primeiro nó
                *l = pt->prox; //avança a cabeça da lista para o seguinte
            }
            else { //senão faz o que já tinha
                ant -> prox = pt -> prox;
            }
            LInt toDelete = pt; //guarda o nó a remover com free
            pt = pt -> prox;
            free(toDelete); //remove o nó que já não é necessário
            r++;
        }
        else {
            ant = pt;
            pt = pt -> prox;
        }
    }

    return r;
}

See this example working on Ideone

0

suggestion:

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

struct lligada
{
    int valor;
    struct lligada *next;
};
typedef struct lligada *LInt;

// protótipos
int removeAll (LInt *l, int x);


int removeAll (LInt *l, int x)
{
    int r = 0;
    LInt pt = *l;
    LInt ant = NULL;

    while (pt != NULL)
    {
        if (pt -> valor == x)
        {
            r++;

            ant->next = pt->next->next; 
            free( pt );
        }

        else
        {
            ant = pt;
            pt = pt -> next;
        }
    }

    return r;
}
  • I appreciate the solution, but still me of the fault Segmentation.

  • then the source of the problem is not in the code posted, but in the code that creates the linked list. My guess is that the last entry on the list has a next value that is not NULL

Browser other questions tagged

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