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