Infinite loop when adding 1 character to a list - c

I am writting a program which adds a character to a list. The problem is that when I have my original list of 5 nodes and I try to add another, everything works, but than when I try to add another one the stampa function becomes infinite.
I can not find the bug. Any help would be welcomed. Here is the code:
struct nodo {
char c;
struct nodo *next;
};
typedef struct nodo *lista;
void mc_coda(lista *l, char el);
void stampa(lista nodo01);
int main() {
int test[5] = {0, 1, 1, 0, 1};
lista nodo01 = malloc(sizeof(struct nodo));
lista nodo02 = malloc(sizeof(struct nodo));
lista nodo03 = malloc(sizeof(struct nodo));
lista nodo04 = malloc(sizeof(struct nodo));
lista nodo05 = malloc(sizeof(struct nodo));
(*nodo01).next = nodo02;
(*nodo02).next = nodo03;
(*nodo03).next = nodo04;
(*nodo04).next = nodo05;
(*nodo05).next = NULL;
(*nodo01).c = 'a';
(*nodo02).c = 'b';
(*nodo03).c = 'c';
(*nodo04).c = 'd';
(*nodo05).c = 'e';
mc_coda(&nodo01, 'e');
mc_coda(&nodo01,
'f'); // If this line is removed everything workd fine, if this line
// if added that it prints infinite f
stampa(nodo01);
return 0;
}
void mc_coda(lista *l, char el) {
if ((*l) == NULL) {
struct nodo temp;
temp.next = NULL;
temp.c = el;
(*l) = &temp;
} else {
while ((*l) != NULL) {
l = &(*(*l)).next;
}
struct nodo temp;
temp.next = NULL;
temp.c = el;
(*l) = &temp;
}
}
void stampa(lista nodo01) {
while (nodo01 != NULL) {
printf("%c\n", (*nodo01).c);
nodo01 = (*nodo01).next;
}
}

Your implementation of mc_coda creates a local variable temp. Because temp is a local variable it will go out of scope when the function exits and then the space will be reused. Instead, you need to allocate space on the heap with malloc. See the below implementation of mc_coda for an example of how to do that:
#include <stdio.h>
#include <stdlib.h>
struct nodo {
char c;
struct nodo *next;
};
typedef struct nodo *lista;
void mc_coda(lista *l, char el);
void stampa(lista nodo01);
int main() {
lista nodo01 = malloc(sizeof(struct nodo));
lista nodo02 = malloc(sizeof(struct nodo));
lista nodo03 = malloc(sizeof(struct nodo));
lista nodo04 = malloc(sizeof(struct nodo));
lista nodo05 = malloc(sizeof(struct nodo));
(*nodo01).next = nodo02;
(*nodo02).next = nodo03;
(*nodo03).next = nodo04;
(*nodo04).next = nodo05;
(*nodo05).next = NULL;
(*nodo01).c = 'a';
(*nodo02).c = 'b';
(*nodo03).c = 'c';
(*nodo04).c = 'd';
(*nodo05).c = 'e';
mc_coda(&nodo01, 'e');
mc_coda(&nodo01, 'f');
stampa(nodo01);
return 0;
}
void mc_coda(lista *l, char el) {
lista tmp = malloc(sizeof(struct nodo));
tmp->next = NULL;
tmp->c = el;
if ((*l) == NULL) {
(*l) = tmp;
} else {
while ((*l) != NULL) {
l = &(*(*l)).next;
}
(*l) = tmp;
}
}
void stampa(lista nodo01) {
while (nodo01 != NULL) {
printf("%c\n", (*nodo01).c);
nodo01 = (*nodo01).next;
}
}

Related

Adding a linked list to another linked list in C programming

I am abeginner trying to add a linked list to another linked list using c. the problem is that the program is entering an infinite loop and i don't know why.
And here's the following c code
typedef struct bookInfo
{
int code;
struct bookInfo *next;
} bookInfo;
typedef struct subscriber
{
int code;
struct bookInfo *books;
struct subscriber *next;
struct subscriber *prec;
} subscriber;
typedef bookInfo *Book;
typedef subscriber *Subscriber;
typedef Subscriber *SubscriberList;
void newBook(Book *bk, int val)
{
bookInfo *new_node = malloc(sizeof(bookInfo));
bookInfo *last = *bk;
new_node->code = val;
new_node->next = NULL;
if (*bk == NULL)
{
*bk = new_node;
}
else
{
while (last->next != NULL)
last = last->next;
last->next = new_node;
}
}
Subscriber Add_book(Subscriber S, Book Bk)
{
bookInfo *newNode = malloc(sizeof(bookInfo));
bookInfo *tmp;
newNode->next = NULL;
newNode->code = Bk->code;
if (S == NULL)
printf("\nl'abonnee est nulle");
else
{
if (S->books == NULL)
S->books = newNode;
else
{
tmp = S->books;
while (tmp != NULL)
tmp = tmp->next;
tmp->next = newNode;
printf("\nl'ajout du livre a ete effectue");
};
}
return S;
};
Hope you guys can help me and thank you. I don't know if the problem in the function newBook or what and here it's my main function
int main()
{
book_ref, sub_ref = NULL;
newSubscriber(&sub_ref);
bookInfo b1 = {20,NULL};
Add_book(sub_ref, &b1);
printf("\n%d : %d", sub_ref->code, sub_ref->books->code);
}
In your code,
while (tmp != NULL) tmp = tmp->next;
When this loop ends, tmp is NULL, so the next line will try accessing null pointer.
You should correct it as, while(tmp->next != NULL)
In order to remove the infinite loop, All i had to do was to define the pointer of books in the subscriber struct to NULL
void newBook(Book *bk, int val)
{
bookInfo *new_node = malloc(sizeof(bookInfo));
bookInfo *last = *bk;
new_node->code = val;
new_node->next = NULL;
new_node->books = NULL;
if (*bk == NULL)
{
*bk = new_node;
}
else
{
while (last->next != NULL)
last = last->next;
last->next = new_node;
}
}
Subscriber Add_book(Subscriber S, Book Bk)
{
bookInfo *newNode = malloc(sizeof(bookInfo));
bookInfo *tmp;
newNode->next = NULL;
newNode->code = Bk->code;
newNode->books = NULL;
if (S == NULL)
printf("\nl'abonnee est nulle");
else
{
if (S->books == NULL)
S->books = newNode;
else
{
tmp = S->books;
while (tmp != NULL)
tmp = tmp->next;
tmp->next = newNode;
printf("\nl'ajout du livre a ete effectue");
};
}
return S;
};
and everything worked.

I get an error when I initialize a string in a structure

I want to initialize a string with every char of it '\0'.(Because I will use gets() later, the first char being not '\0' is OK.)
So I use assign the string with "a".
Here is my code:
typedef struct node
{
char name[12] = "a";
struct node* next;
struct node* prev;
struct node* lead;
} node;
However,
if I change char name[12] = "a"; tochar name[12]; , it will be OK,
if I don't change, it will give an error message:
C:\UsersDesktop\exp1-2\main.c|7|error: expected ':', ',', ';', '}' or '__attribute__' before '=' token| and C:\Users\Desktop\exp1-2\main.c|25|error: 'node' {aka 'struct node'} has no member named 'name'|
Thank you in advance!
Above shows my part of code, if you wanna see a complete one, HRER are my complete code:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef struct node
{
char name[12] = "a";
struct node* next;
struct node* prev;
struct node* lead;
} node;
node* init()
{
node* huzong = (node*)malloc(sizeof(node));
node* wangzong = (node*)malloc(sizeof(node));
node* zhangzong = (node*)malloc(sizeof(node));
node* lizong = (node*)malloc(sizeof(node));
node* zhangsan = (node*)malloc(sizeof(node));
node* lisi = (node*)malloc(sizeof(node));
node* laoliu = (node*)malloc(sizeof(node));
node* xiaopeng = (node*)malloc(sizeof(node));
node* xiaochen = (node*)malloc(sizeof(node));
strcpy(huzong->name, "胡总");
huzong->lead = NULL;
huzong->prev = NULL;
huzong->next = wangzong;
strcpy(huzong->name, "王总");
wangzong->lead = zhangsan;
wangzong->prev = huzong;
wangzong->next = zhangzong;
strcpy(huzong->name, "张总");
zhangzong->lead = NULL;
zhangzong->prev = wangzong;
zhangzong->next = lizong;
strcpy(huzong->name, "黎总");
lizong->lead = NULL;
lizong->prev = zhangzong;
lizong->next = NULL;
strcpy(huzong->name, "张三");
zhangsan->lead = NULL;
zhangsan->prev = NULL;
zhangsan->next = lisi;
strcpy(huzong->name, "李四");
lisi->lead = xiaopeng;
lisi->prev = zhangsan;
lisi->next = laoliu;
strcpy(huzong->name, "老刘");
laoliu->lead = NULL;
laoliu->prev = lisi;
laoliu->next = NULL;
strcpy(huzong->name, "小彭");
xiaopeng->lead = NULL;
xiaopeng->prev = NULL;
xiaopeng->next = xiaochen;
strcpy(huzong->name, "小陈");
xiaochen->lead = NULL;
xiaochen->prev = xiaopeng;
xiaochen->next = NULL;
return huzong;
}
void list(node* head)
{
printf("%s", head->name);
list(head->lead);
list(head->next);
}
node* find(node* head, char* ex_name)
{
int i = 1;
i = strcmp((head->name), *ex_name);
if(i==0)
{
return head;
}
find(head->lead, ex_name);
find(head->next, ex_name);
return NULL;
}
void lead(node* new_node, node* existing)
{
existing->lead = new_node;
new_node->lead = NULL;
new_node->next = NULL;
new_node->prev = NULL;
}
void follow(node* new_node, node* existing)
{
existing->next = new_node;
new_node->prev = NULL;
new_node->lead = NULL;
new_node->next = NULL;
}
int main()
{
char input[60]="a";
char new_name[12]="a";
char ex_name[12]="a";
while(1)
{
node* head;
node* temp = NULL;
head = init();
gets(input);
for(int i = 0; i < 50; i++)
{
//init初始化实现
if(input[i]=='i'&&input[i+1]=='n'&&input[i+2]=='i'
&&input[i+3]=='t')
{
init();
printf("链表构造完成,现有9名员工");
}
//list遍历功能实现
if(input[i]=='l'&&input[i+1]=='i'&&input[i+2]=='s'
&&input[i+3]=='t')
{
list(head);
}
//lead功能实现
if(input[i]=='l'&&input[i+1]=='e'&&input[i+2]=='a'
&&input[i+3]=='d')
{
for(int j=0; j<=i-2; j++)
{
new_name[j] = input[j];
}
printf("%s", new_name);
for(int k=i+8; k<=i+20; k++)
{
ex_name[k-i-8] = input[k];
}
printf("%s", ex_name);
node* new_node = (node*)malloc(sizeof(node));
strcpy(new_node->name, new_name);
printf("strcpy完成");
temp = find(head, ex_name); //问题在此
printf("find完成");
temp->lead = new_node;
}
}
}
}
Your code is not valid C, as you cannot initialize struct fields in this manner.
char name[12] = "a";
Were you allocating the memory for name dynamically, I'd suggest using calloc which sets all bytes to zero.
For instance:
typedef struct node {
char *name;
...
} node;
node *new_node(char *name) {
node *n = malloc(sizeof(node));
n->name = calloc(12);
strncpy(n->name, name, 11);
return n;
}

Why aren't nodes adding properly and why is it printing in reverse? (singly linked list)

SOLVED
The problem could also be solved by copying the head into another variable after adding new nodes.
A more logical solution would be to do as the answer says.
I'm practicing on a simple linked list implementation, wanted to explore pointers more too. why doesn't my code add nodes properly?
typedef struct Node{
int info;
struct Node* next;
}Node;
void createList(Node** node, int info){
*node = calloc(1, sizeof(Node));
(*node)->info = info;
(*node)->next = NULL;
}
Node* newNode(int info)
{
Node* newNode;
newNode = calloc(1, sizeof(Node));
newNode->info = info;
newNode->next = NULL;
return newNode;
}
void addNode(Node** node, int info){
int adaugat = 0;
if(*node == NULL){
createList(node, info);
adaugat = 1;
}
if(adaugat == 0)
{
Node **aux = node;
while((*aux)->next != NULL)
{
*aux = (*aux)->next;
}
(*aux)->next = newNode(info);
adaugat = 1;
}
}
void printList(Node* node){
int i = 1;
Node* aux;
aux = node;
while(aux != NULL)
{
printf("%d_[%d]--",i, aux->info );
i++;
aux = aux->next;
}
}
int main(int argc, char const *argv[])
{
Node *nod = NULL;
int key = 5;
createList(&nod, key);
addNode(&nod, 5);
addNode(&nod, 3);
addNode(&nod, 4);
addNode(&nod, 1);
printList(nod);
return 0;
}
I've attempted shifting around with pointers and function calling inputs in main() but all I got were more warnings and segfaults.
The output here from main() is 1_[4]--2_[1]-- when it should have been
1_[5]--2_[3]--3_[4]--4_[1]--
In this snippet of the function addNode
if(adaugat == 0)
{
Node **aux = node;
while((*aux)->next != NULL)
{
*aux = (*aux)->next;
}
(*aux)->next = newNode(info);
adaugat = 1;
}
more precisely on the line *aux = (*aux)->next; you are shifting the list at the same time you are walking through it because of the Node ** aux. Hence it will always look like your list has two elements.
If you want to add an element at the end of the list, you have to traverse the list without modifying it, that is,
if(adaugat == 0)
{
Node *aux = *node;
while(aux->next != NULL)
{
aux = aux->next;
}
aux->next = newNode(info);
adaugat = 1;
}
The problem lies in the following block of code
if(adaugat == 0)
{
Node **aux = node;
while((*aux)->next != NULL)
{
*aux = (*aux)->next;
}
(*aux)->next = newNode(info);
adaugat = 1;
}
The variable node is not getting dereferenced and using a double pointer here is unnecessary. Changing that part to the following will give you the desired output...
if(adaugat == 0)
{
Node *aux = *node;
while(aux->next != NULL)
{
aux = aux->next;
}
aux->next = newNode(info);
adaugat = 1;
}
Hope this helps.

printing a pointer value

i have this issue while trying to print *p value while p is pointed to a nodo of the list (obviusly i would like to print the nodo.info value)
here is the code, hope u understand:
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
} ;
typedef struct nodo nodo;
int main (void) { // just declaring my 3 nodos
struct nodo *p;
struct nodo anodo;
struct nodo bnodo;
struct nodo cnodo;
anodo.info = 200;
anodo.prec = NULL;
anodo.succ = NULL;
bnodo.info = 22;
bnodo.prec = NULL;
bnodo.succ = NULL;
cnodo.info = 2000;
cnodo.prec = NULL;
cnodo.succ = NULL;
anodo.succ = &bnodo;
bnodo.prec = &anodo;
bnodo.succ = &cnodo;
cnodo.prec = &bnodo;
p = &anodo;
printf("\n%d\n", checklist (p)); // calling function
return 0;
}
nodo *checklist (struct nodo *p) {
int j=0;
while (p != NULL) {
if (p->info >= p->succ->info) { //if first element is major or same than next
p=p->succ;
} else {
while (p != NULL) {
if (p->info >= p->succ->info) { //same
p=p->succ;
j++;
} else {
p = NULL;
}
}
}
}
while (j != 0) {
p = p->prec; //used a counter to get back to the first nodo in wich next was less than prev
j--;
}
return p;
}
feel free to ask any details
p = checklist (p);
if (p)
printf("\n%d\n", p->info);
You need to return the nodo.info then
int checklist (struct nodo *p) {
int j=0;
while (p != NULL) {
/* avoid this p->succ->info */
if (p->info >= p->succ->info) { //if first element is major or same than next
p = p->succ;
} else {
while (p != NULL) {
if (p->info >= p->succ->info) { //same
p = p->succ;
j++;
} else {
p = NULL;
}
}
}
}
while (j != 0) { p = p->prec; //used a counter to get back to the first nodo in wich next was less than prev
j--;
}
return p->info;
}
or in main
int info
struct nodo *found;
found = checklist(p);
if (found != NULL)
printf("\n%d\n", found->info);

how to add a newly created node to linklist?

here is my code, i can only add the node to the head of the linklist, but how to append to the tail to the linklist? thanks
struct recordNode {
char name[256];
char event[128]; /
float time;
struct recordNode* next;
};
struct recordNode* temp;
struct recordNode* aRecordPointer = NULL;
struct recordNode* createRecord(char* name, char* event, float time) {
temp = (struct recordNode*)malloc(sizeof(struct recordNode));
strcpy(temp->name, name);
strcpy(temp->event, event);
temp->time = time;
/* link up */
if (aRecordPointer == NULL) {
aRecordPointer = temp;
temp->next = NULL;
} else {
temp->next = aRecordPointer;
aRecordPointer = temp;
}
return aRecordPointer;
}
int main() {
struct recordNode* record = createRecord("1abc", "abc", 12.25);
record = createRecord("2abc", "abc", 25.98);
record = createRecord("3abc", "abc", 52.60);
}
/* now result:
3abc abc 12.25
2abc abc 25.98
1abc abc 52.60
needed result:
1abc abc 52.6
2abc abc 25.98
3abc abc 12.25
*/
Assuming that aRecordPointer is your pointer to the head (first) element of list, you need to iterate the list from head to tail (last).
struct recordNode* createRecord(char* name, char* event, float time){
temp = (struct recordNode*)malloc(sizeof(struct recordNode));
strcpy(temp->name, name);
strcpy(temp->event, event);
temp->time = time;
temp->next = NULL;
if (aRecordPointer == NULL) {
aRecordPointer = temp;
}
else {
struct recordNode* pLast = aRecordPointer;
/* find the last element */
while(pLast->next != NULL) {
pLast = pLast->next;
}
/* get linked */
pLast->next = temp;
}
return aRecordPointer;
}
Assuming that aRecordPointer is a pointer to the last Node, modify your code as below:
struct recordNode* createRecord(char* name, char* event, float time)
{
temp = (struct recordNode*)malloc(sizeof(struct recordNode));
strcpy(temp->name, name);
strcpy(temp->event, event);
temp->time = time;
//I have added this line as well.
temp->next = NULL;
/* link up */
if (aRecordPointer == NULL)
{
aRecordPointer = temp;
}
else
{
aRecordPointer->next = temp;
aRecordPointer = temp;
}
return aRecordPointer;
}
Also note that you should always have a pointer to Head (First Node) in order to traverse the linked list later.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void Traverse();
struct recordNode {
char name[256];
char event[128];
float time;
struct recordNode* next;
};
struct recordNode* temp;
struct recordNode* aRecordPointer = NULL;
struct recordNode* createRecord(char* name, char* event, float time) {
struct recordNode * ToTraverseTheLinkedList;
temp = (struct recordNode*)malloc(sizeof(struct recordNode));
strcpy(temp->name, name);
strcpy(temp->event, event);
temp->time = time;
temp->next = NULL;
/* link up */
if (aRecordPointer == NULL) {
aRecordPointer = temp;
//temp->next = NULL;
}
else
{
ToTraverseTheLinkedList = aRecordPointer;
while(ToTraverseTheLinkedList->next != NULL)
{
ToTraverseTheLinkedList = ToTraverseTheLinkedList ->next;
}
ToTraverseTheLinkedList->next = temp;
}
return aRecordPointer;
}
int main() {
createRecord("1abc", "abc", 12.25);
//Traverse();
createRecord("2abc", "abc", 25.98);
createRecord("3abc", "abc", 52.60);
Traverse();
}
void Traverse()
{
struct recordNode * temp;
temp = aRecordPointer;
while(temp != NULL)
{
printf("%s\n",temp->name);
printf("%s\n",temp->event);
printf("%f\n",temp->time);
temp = temp->next;
}
}

Resources