Error Segmentation fault (core dumped) Double circular list

0

I've been trying to make a Double Circular List for hours. I have tried to correct all the errors but it gave a error 'Segmentation fault (core dumped)' that I have no idea what it is. Can anyone help me please?

Below is my code:

//Arquivo circDuplList.c
#include <stdio.h>
#include <stdlib.h>
#include "cdlist.h"


struct cdlst{
int info;
cdLst* ant;
cdLst* prox;
};

/*Create an empty circ dupl list*/
cdLst* create_empty(void)
{
    return NULL;
}

/*Insert a node to the front of the circular list*/
cdLst* insert_front(cdLst* cdl, int info)
{
cdLst* p = (cdLst*)malloc(sizeof(cdLst));
p->info = info;
p->prox = cdl;
if(cdl != NULL){
    cdLst* aux = cdl;
    while(aux->prox != cdl){
        aux = aux->prox;
    }
    cdl->ant = p;
    p->ant = aux;
    aux->prox = p;
}else{
    p->prox = p->ant;
    p->ant = p->prox;
}
cdl = p;
return cdl;
}

/*Insert a node to the end of the circular list*/
cdLst* insert_end(cdLst* cdl, int info)
{
    cdLst* n = (cdLst*) malloc(sizeof(cdLst));
    n->info = info;
    if(cdl != NULL){
        cdLst* p = cdl;
        while(p->prox != NULL){
            p = p->prox;
        }
        p->prox = n;
        n->prox = cdl;
        n->ant = p;
        cdl->ant = n;
    }
    else{
        n->ant = n->prox = NULL;
        return n;
    }
    return cdl;
}

/*Remove a node from the list*/
void retira(cdLst* cdl,int info)
{
    if(cdl == NULL){
        printf("The list is empty");
        exit(1);
    }
    cdLst* p = cdl;
    while(p->prox != cdl && p->info != info)
        p = p->prox;
    if(p->prox == cdl && p->info != info){
        exit(1);
    }
    if(p == cdl){
        cdl = cdl->prox;
        cdl->ant = p->ant;
    }
    p->ant->prox = p->prox;
    free(p);
}

/*Print the list*/
void cdl_print(cdLst* cdl)
{
    cdLst* p = NULL;
    printf("\n%d",p->info);
    p = p->prox;
    while(p != cdl)
        printf("\n%d",p->info);
}

/*Print the list in the reverse order*/
//void cdl_print_rev(cdLst* cdl);

/*Verify if the list is empty*/
int empty(cdLst* cdl)
{
    return cdl == NULL;
}

/*Free memory of the list*/
//void cdl_free();
//Arquivo main.c
#include <stdio.h>
#include <stdlib.h>
#include "cdlist.h"

int main(void){
    cdLst* l = create_empty();
    int v = empty(l);
    printf("%d",v);
    l = insert_front(l,3);
    v = empty(l);
    printf("%d",v);
    l = insert_front(l,2);
    l = insert_front(l,3);
    l = insert_front(l,8);
    l = insert_front(l,65);
    l = insert_front(l,3);
    cdl_print(l);
}
    
asked by anonymous 17.10.2018 / 06:45

1 answer

1

If the list is circular, then you do not have to go through it in insert_front because that means that the "end" is just before the beginning. So in insert_front , if cdl is not NULL , you can do just that:

    p->prox = cdl;
    p->ant = cdl->ant;
    p->ant->prox = p;
    p->prox->ant = p;

That is, binds the new element the cdl e to the element that precedes the cdl and connects those two elements to p .

Similarly, if the list is circular then it does not make sense to have both insert_front to insert at the beginning and insert_end to insert at the end. The start and end of the list are exactly the same places. So you only need one of them.

When trying to insert the first node, cdl is NULL . insert_front does this:

cdLst* insert_front(cdLst* cdl, int info)
{
cdLst* p = (cdLst*)malloc(sizeof(cdLst));
p->info = info;
p->prox = cdl;
if(cdl != NULL){
    // ...
}else{
    p->prox = p->ant;
    p->ant = p->prox;
}

Note the order of how pointers of p will be defined:

p->prox = cdl;
p->prox = p->ant;
p->ant = p->prox;

The second line ( p->prox = p->ant; ) will copy garbage from p->ant to p->prox , overwriting cdl . At this time, p->ant is garbage because it has not been defined anywhere. The third line will have no effect.

What you need in the case of cdl to be NULL is this:

p->prox = p;
p->ant = p;

The reason is that the list is circular, so when it starts with a single element, that element itself has itself as next and previous.

While in insert_front , you have this:

return cdl;

The first time, cdl is NULL , it will create the first node in the list and return NULL . Returning NULL means that you create a node and lose it right away. That way, you can never create anything! What you wanted to return is p .

In cdl_print , this can not work for obvious reasons:

cdLst* p = NULL;
printf("\n%d",p->info);

Still in cdl_print , see this code:

p = p->prox;
while(p != cdl)
    printf("\n%d",p->info);

Note that since p is never changed within while , then this is an infinite loop.

I have not checked the retira function and will not know the insert_end . I also removed create_empty and empty because I consider them unnecessary, since create_empty only returns NULL always doing nothing and empty just checks if something is NULL or not and you do not need a function to do this.

Your code looks like this:

//Arquivo circDuplList.c
#include <stdio.h>
#include <stdlib.h>

typedef struct cdLst{
    int info;
    struct cdLst* ant;
    struct cdLst* prox;
} cdLst;

/*Insert a node to the front of the circular list*/
cdLst* insert_front(cdLst* cdl, int info) {
    cdLst* p = (cdLst*)malloc(sizeof(cdLst));
    p->info = info;
    if (cdl != NULL) {
        p->prox = cdl;
        p->ant = cdl->ant;
        p->ant->prox = p;
        p->prox->ant = p;
    } else {
        p->prox = p;
        p->ant = p;
    }
    cdl = p;
    return p;
}

/*Print the list*/
void cdl_print(cdLst* cdl) {
    printf("\n%d",cdl->info);
    for (cdLst *p = cdl->prox; p != cdl; p = p->prox) {
        printf("\n%d",p->info);
    }
}

int main(void){
    cdLst* l = NULL;
    l = insert_front(l,3);
    l = insert_front(l,2);
    l = insert_front(l,3);
    l = insert_front(l,8);
    l = insert_front(l,65);
    l = insert_front(l,3);
    cdl_print(l);
}

Here's the output:

3
65
8
3
2
3

See here working on ideone.

    
17.10.2018 / 07:43