Miguel Freitas
Miguel Freitas

Reputation: 60

Linked list help requested

This is my struct for a linked list:

typedef struct intervalo *Lista;

typedef struct intervalo
{
    int num;
    Lista next;
}Lista_int;

This is the part of my code (I made) that destroys the list:

Lista destroi_lista_res(Lista lista)
{
    Lista temp_ptr;
    while (lista->next!= NULL)
    {
        temp_ptr = lista;
        lista= lista->next;
        free(temp_ptr);
    }
    free(lista);
    return NULL;
}

Unfortunately, my program hangs when this function is called.. Specifically, while (lista->next!= NULL) never terminates.

My question: Why does this line cause an endless loop?


Additional code detail:

In main(), two lists are created.

/* Create linked list. */
Lista cria_lista_cab()
{
    Lista aux;
    aux=(Lista)malloc(sizeof(Lista_int));
    if(aux!=NULL)
    {
        aux->next=NULL;
    }
    return aux;
}

The following function is used to add number nodes to end of the two lists:

/* Insert node at the list tail. */
void insere_elem(Lista *lista,int num)
{
    Lista aux,ant_pos=*lista,pos=ant_pos->next;
    aux=(Lista)malloc(sizeof(Lista_int));
    while(pos!=NULL)
    {
        ant_pos=ant_pos->next;
        pos=pos->next;
    }
    aux->num=num;
    aux->next=pos;
    ant_pos->next=aux;
}

The next function combines the number nodes of both lists, eliminating duplicates in increasing numeric order. The resulting list is returned:

Lista cria_lista_una(Lista lista1,Lista lista2)
{
    Lista lista_res=cria_lista_cab();
    lista1=lista1->next;
    lista2=lista2->next;
    while(lista1!=NULL && lista2!=NULL)
    {
        if(lista1->num<lista2->num)
        {
            insere_elem(&lista_res,lista1->num);
            printf("\n1 %d %d",lista1->num,lista2->num);
            if(lista1!=NULL)
                lista1=lista1->next;
        }
        else if(lista2->num<lista1->num)
        {
            insere_elem(&lista_res,lista2->num);
            printf("\n2 %d %d",lista1->num,lista2->num);
            if(lista2!=NULL)
                lista2=lista2->next;
        }
        else if(lista2->num==lista1->num)
        {
            printf("\n3 %d %d",lista1->num,lista2->num);
            if(lista1!=NULL)
                lista1=lista1->next;
            else if(lista2!=NULL)
                lista2=lista2->next;
        }
    }
    if(lista1!=NULL)
    {
        while(lista1!=NULL)
        {
            insere_elem(&lista_res,lista1->num);
            lista1=lista1->next;
        }
    }
    else if(lista2!=NULL)
    {
        while(lista2!=NULL)
        {
            insere_elem(&lista_res,lista2->num);
            lista2=lista2->next;
        }
    }
    return lista_res;
}

The following function is used to print a list.

void imprime_lista_res(Lista lista)
{
    lista=lista->next;
    while(lista!=NULL)
    {
        printf("\nNum-> %d",lista->num);
        lista=lista->next;
    }
}

Everything seems to function as expected, except for when cleaning up when destroi_lista_res() is called and the program hangs. .

Upvotes: 1

Views: 93

Answers (3)

user3629249
user3629249

Reputation: 16540

given your code:

void insere_elem(Lista *lista,int num)
{
    Lista aux,ant_pos=*lista,pos=ant_pos->next;
    aux=(Lista)malloc(sizeof(Lista_int));

and remembering that Lista is actually defined as a pointer to an instance of the struct Lista_int

your code becomes: Note: Your actually appending a node to the linked list, not inserting

void insere_elem(struct Lista_int* *lista,int num) //note the ptr to ptr
{
    struct Lista_int * aux;
    struct Lista_int * ant_pos=*lista; //gets ptr to first instance of struct Lista_int
    struct Lista_int * pos=ant_pos->next; // get ptr to NULL or second instance of..

    // get ptr to new instance of struct
    aux=(struct Lista_int*)malloc(sizeof(Lista_int));

    // HERE should be checking that malloc() was successful
    // otherwise, the lines:
    //  aux->num=num;
    //  aux->next=pos;
    // will be writing to offsets from address 0 
    // will probably cause a crash


    // step forward through linked list to find last struct
    while(pos!=NULL)
    {
        ant_pos=ant_pos->next; // step ptr to prior struct
        pos=pos->next;         // step ptr to current struct
    }

    aux->num=num;  // set fields in new struct
    aux->next=pos; // pos is already NULL, so probably (for clarity) just use NULL
    ant_pos->next=aux; // set old struct instance ptr to new instance of struct
}

also, regarding this code:

while(lista2!=NULL)
{
    insere_elem(&lista_res,lista2->num);
    lista2=lista2->next;
}

this loop starts at the head of the linked list 'lista_res' so for every element in the current linked list, it adds yet another element In general, this means the linked list doubles in size with every entry into this code sequence

Upvotes: 0

rkp
rkp

Reputation: 13

In your distroi function what will it does if Lista is already NULL, then it will through segmentation fault. But according to you if you are coming out of that function then you may not creating your list properly. first make the change as follows:

Lista destroi_lista_res(Lista lista)
{
    Lista temp_ptr;
    while (lista!= NULL)
    {
        temp_ptr = lista;
        lista= lista->next;
        free(temp_ptr);
    }
    return NULL;
}

Another thing which is need to take care is that "have you created your list properly, if it is then you print function will not work properly. to do ensure this please make a dummy traverse function for debugging purpose which just traverse the list in same you as in your distroi function.

Upvotes: 0

R Sahu
R Sahu

Reputation: 206697

That's probably because lista is NULL to start with.

Change the function to:

Lista destroi_lista_res(Lista lista)
{
    Lista temp_ptr;
    while (lista!= NULL)
    {
        temp_ptr = lista;
        lista= lista->next;
        free(temp_ptr);
    }
    return NULL;
}

Upvotes: 3

Related Questions