Home > Back-end >  Circular list in infinite loop while printing
Circular list in infinite loop while printing

Time:10-02

I have a problem where printing a circular list is in an infinite loop. In the code, I created a function that receives a value n that is the amount of elements that will be inserted in the list and a vector v. And I loop through each element of the vector and add it to the list according to the size of n. I don't believe I have a problem with that code block, because the error is happening during printing, only when it gets to the last node

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

struct circular_list {
    int info;
    struct circular_list *prox;
};
typedef struct circular_list CircularList;

CircularList* startList(CircularList *L){
    return NULL;
}

void printList(CircularList *L){
    CircularList *p=L;  

    if (p==NULL)
        printf("\nList is empty");
    else{
        do{
            if (p->prox==L) 
                printf("%d", p->info);
            else
                printf("%d -> ", p->info);
            p = p->prox;
        }while(p!=L);       
    }
    printf("\n");
}


CircularList *build(int n, int *v)
{
    CircularList *head = NULL;
    for (int i = 0; i < n; i  )
    {
        CircularList *auxList = (CircularList*)malloc(sizeof(CircularList));
        auxList->info = v[i];
        if (head == NULL) {
            auxList->prox = auxList;
        } else {
            auxList->prox = head;
        }
       
        head = auxList;
    }
    return head;
}

int main() {
    CircularList* list;
    int vector[5] = {13, 38, 21, 71, 21};

    list = startList(list);
    list = build(5, vector);
    printList(list);

    return 0;
}

Can anyone help me?

CodePudding user response:

The output of this program begins as:

21 -> 71 -> 21 -> 38 -> 13 -> 13 -> 13 -> 13 -> 13 -> 13

From this, we can see that the list is not being built correctly. The first node created points to itself, and the function is not returning the intended head node.

In fact, the list is being linked in reverse, which is easier to see if you change the values of your vector:

int vector[5] = {13, 38, 21, 71, 51};
51 -> 71 -> 21 -> 38 -> 13 -> 13 -> 13 -> 13 -> 13 -> 13

Here is a working function, where we isolate the head node.

CircularList *build(int n, int *v)
{
    CircularList *head = NULL;
    CircularList *current = NULL;

    for (int i = 0; i < n; i  ) {
        CircularList *auxList = malloc(sizeof *auxList);
        auxList->info = v[i];

        if (head == NULL) {
            head = auxList;
        } else {
            current->prox = auxList;
        }

        current = auxList;
    }

    current->prox = head;

    return head;
}

CodePudding user response:

(edited)

I modified main() like so to debug. The problem is the build() code; the first item in the array, which is the last list node you reach, points to itself.

int main() {

    CircularList* list;
    int vector[5] = {13, 38, 21, 71, 21};

    list = startList(list);
    list = build(5, vector);
    // printList(list);

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    return 0;
}

output:

list node info: 21
list node prox: 0x7f8ae8405c50
list node info: 71
list node prox: 0x7f8ae8405c40
list node info: 21
list node prox: 0x7f8ae8405c30
list node info: 38
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20

CodePudding user response:

Slow day, so here's a rewrite of your code. Don't forget that you have to free() heap storage to prevent memory leaks.

Note the renaming of your struct: A node is a node. It is the code that makes this a circular LL, as compared to an linear LL. A node is a node is a node... A node is not (usually) a list...

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

typedef struct node { // combine things. Don't write more lines of code.
    int info;
    struct node *prox;
} node_t; // short & sweet name

node_t *printit( node_t *L ) {
    // think about re-using as much code as you can
    char *use = "\nList is empty"; // set up defaults in case they are used.
    if( L ) {
        node_t *p = L;
        use = ""; // default
        do {
            printf( "%s%d", use, p->info );
            use = " -> "; // replaced
        } while( (p = p->prox) != L ); // combine things
        use = ""; // to output only a LF
    }
    puts( use );
    return L; // magic can happen. see 'main()'
}

node_t *freeit( node_t *p ) { // Missing from your code
    while( p && p != p->prox ) {
        node_t *pDel = p->prox;
        p->prox = p->prox->prox;
        free( pDel );
    }
    free( p );
    return NULL;
}

node_t *buildit( int n, int *v ) {
    node_t *head = NULL, *tail = NULL;

    for( int i = 0; i < n; i   ) {
        node_t *p = malloc( sizeof *p );
        /* omitting test for NULL */ // be explicit
        p->info = v[i];

        // combine what you can to avoid too much code
        // use the power of C syntax
        if( head == NULL )
            head = tail = p->prox = p;
        else
            (tail = tail->prox = p)->prox = head;
    }

    return head;
}

int main() {
    // use short, meaningful names in trivial functions
    int v[5] = { 13, 38, 21, 71, 21 };

    node_t *l = buildit( sizeof v/sizeof v[0], v );
    printit( l );
    l = freeit( l ); // don't forget about this!
    // setting 'l' to NULL ensures it is NULL if accidentally used again

    /* more code ?? */

    // and a bit of magic...
    freeit( printit( buildit( sizeof v/sizeof v[0], v ) ) );

    return 0;
}
13 -> 38 -> 21 -> 71 -> 21
13 -> 38 -> 21 -> 71 -> 21
  • Related