Reputation: 29
I have see some other posts about how to print out a linked list, but none of them were helpful to me, so I decided to post my own code. Here is the problem:
I am able to add in a name and age perfectly fine, but the second I add in another name and age it overwrites the previous one.
So if i input:
Matt and 21, then charles and 34. It will only output charles and 34. How do I get it to output everything? Thank you in advance for the help! :)
Here is my code:
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#define pause system ("pause")
// prototype variables
struct node * initnode(char*, int);
void printnode(struct node*);
struct node{
char name[20];
int age;
struct node *next;
};
struct node *head = (struct node*) NULL;
struct node *end = (struct node*) NULL;
struct node* initnode(char *name, int age){
struct node *ptr;
ptr = (struct node*) calloc(3, sizeof(struct node));
if(ptr == NULL)
return (struct node*) NULL;
else {
strcpy(ptr->name, name);
ptr->age = age;
return ptr;
}
}
void printnode(struct node *ptr) {
printf("Name -> %s\n", ptr->name);
printf("Age -> %d\n", ptr->age);
}
main() {
char name[20];
int age, choice = 1;
struct node *ptr;
while(choice != 3){
system("cls");
printf("1. Add a name\n");
printf("2. List nodes\n");
printf("3. Exit");
printf("\nEnter Menu Selection: ");
scanf("%d", &choice);
switch(choice) {
case 1: printf("\nEnter a name: ");
scanf("%s", name);
printf("Enter age: ");
scanf("%d", &age);
ptr = initnode(name, age);
break;
case 2: if(ptr == NULL) {
printf("Name %s not found\n", name);
} else
printnode(ptr);
pause;
break;
case 3: exit(3);
default: printf("Invalid Entry");
}// end of switch
}// end of main
}
Oh and I know that some of the "#include's" might not be useful. I've been adding and deleting code all day.
Upvotes: 1
Views: 13310
Reputation: 125037
I am able to add in a name and age perfectly fine, but the second I add in another name and age it overwrites the previous one.
Your code doesn't overwrite the previous node, it replaces it with a new node and leaks the one you had before. (A leak is a piece of memory that you've allocated and then lost any pointers to, so that you can never deallocate it.) Here's the line that creates a new node:
ptr = initnode(name, age);
If ptr
is the pointer to the first node in the list, you should be adding the new node to the end of the list, not assigning it to ptr
.
Upvotes: 0
Reputation: 43616
Just a remamrk:
ptr = (struct node*) calloc(3, sizeof(struct node));
is wrong because you are allocating 3 * sizeof(struct node)
and it should be
ptr = (struct node*) calloc(1, sizeof(struct node));
Your code is missing many things. you are not linking the node you create to any linked list. in the whole code you are not using next
. You have to work more on this code.
The problem is not only coming from the print of the linked list. the problem come from how to create the linked list
I can suggest to you a template of linked list which can help in developing such program. this template contains functions and macro to treate linked list like
you can get the linked list template (list.h) from this link
The following link contains an example of how use it
Please refer to this paragraph in the above link
With very little modifications (removing hardware prefetching of list items) we can also use this list in our applications. A usable version of this file is available here for download.
Upvotes: 1
Reputation: 20203
While you have defined head
and end
pointers, which would make a linked list, you are not actually using these to store your new information. After having created your new node and storing it in the ptr
variable, you don't actually store it in the list.
I would suggest adding another method, addnode
, which adds this newly-created node to the linked list defined by the head
and end
pointers.
void addnode(struct node *ptr) {
if (end == NULL) {
head = ptr;
end = ptr;
}
else {
end = end->next = ptr;
}
}
Broadly, we check if we have any items already in the list; if not, both the start and the end of the list will be represented by the same node: the only one in the list! Otherwise, we let the node after the current end be the node to add, and then move our global end
pointer to what is now the last node.
This allows us to maintain a chain of more than one node (entry in the list). We must then, when printing the entire list, follow this entire chain, from the first node (head
) to the last. We can do this with a simple loop: instead of simply calling printnode()
on the temporary ptr
variable we maintain in main()
, we write:
struct node *current = head;
while (current != end) {
printnode(current);
current = current->next;
}
Upvotes: 1
Reputation: 49523
This line here:
ptr = initnode(name, age);
is why you're always overwriting the name/age, because you declared a local node called ptr
and every time you add a value you overwrite that node with the next node.
See that struct node *next;
element in your node structure? You need to point that to the next node created in order to have more than 1 node, sort of like:
ptr->next = initnode(name, age);
There's a special case of the first node when it comes to linked lists, your first node ptr
is empty, so when your list is 0 in length, you need to set ptr
from init_node()
, the next time you need to set ptr
's next
element, and then you need to update ptr so that it is the current node:
ptr = ptr->next;
Of course doing this causes you to "loose" the start for the list. That's where your head
comes in. When you start if you initialize head
to ptr
, then never move head, you'll always remember where the start of your list is.
You also have a variable:
struct node *end = (struct node*) NULL;
You'll have to keep updating that with every addition in order to always point to the last element added... if you care. Normally end
or last
or tail
pointers are if you're going to make a double linked list.
Upvotes: 0