While inserting node at end in linked list ,my code is running in infinite loop.
IDE Used-Eclipse
64 bit OS
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int info;
struct Node *next;
}node;
node *head;
node *ptr1;
void insert(int x);
void show();
int main()
{
int i,x,n;
puts("Enter number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
puts("Enter elements");
scanf("%d",&x);
insert(x);
}
show();
return 0;
}
//To insert the data in linked list
void insert(int x)
{
node *ptr;
ptr1=head;
ptr=(node*)malloc(sizeof(node));
ptr->info=x;
if(head==NULL)
{
ptr->next=head;
head=ptr;
}
else
{
ptr1->next=NULL;
ptr1=ptr;
}
}
//To print the details of list
//Unable to figure out this function
void show()
{
while(ptr1->next!=NULL)
{
printf("%d\n",ptr1->info);
ptr1=ptr1->next;
}
}
The ptr1 is set to head each time your code enters the insert function then setting it to ptr in the else subsection but nothing pointing to any previous items.
Here is an example in case you need one.
typedef struct Node
{
int info;
struct Node *next;
}node;
node *head = NULL;
void insert(int x);
void show();
int main()
{
int i,x,n;
puts("Enter number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
puts("Enter elements");
scanf("%d",&x);
insert(x);
}
show();
return 0;
}
void insert(int x)
{
node *ptr = (node*)malloc(sizeof(node));
ptr->info=x;
ptr->next=head; /* this will always add the new entry at the beginning of the list all you need it to initialize the head to NULL*/
head = ptr; /* move the head so that it points to the newly created list element */
}
void show()
{
node *ptr1 = head;
printf("%d\n",ptr1->info); /* print the head */
while(ptr1->next!=NULL) /* now walk the list remember it first looks if the next pointer in the list is null first then it jumps on next element in case it is not*/
{
ptr1=ptr1->next;
printf("%d\n",ptr1->info);
}
}
Remember to create a function to free up the list elements before exiting the main.
Your two functions can be simplified. A singly linked list is very easy to implement. I would also improve the functions by taking the list pointer as an argument, and in the case of insert() return the new head of the list: but get it working first! Note there is no reason or need to declare global variables when their only use is local to a function.
// insert new node at head of the list
void insert(int x) {
node *ptr = malloc(sizeof(node));
if (ptr == NULL) {
printf ("malloc failure\n");
exit (1);
}
ptr->info = x;
ptr->next = head; // append existing list
head = ptr; // new head of list
}
// show the linked list
void show() {
node *ptr = head; // start at head of list
while (ptr != NULL) {
printf("%d\n", ptr->info);
ptr = ptr->next; // follow the link chain
}
}
EDIT here is code to add to the tail of a linked list
// insert new node at tail of the list
void insert2(int x) {
node *tail = head;
node **last = &head;
node *ptr;
while (tail) {
last = &tail->next;
tail = tail->next;
}
ptr = malloc(sizeof(node));
if (ptr == NULL) {
printf ("malloc failure\n");
exit (1);
}
ptr->info = x;
ptr->next = NULL;
*last = ptr;
}
Related
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//defined a data structure "node" which stores an int and a pointer to a node
typedef struct node
{
int number;
struct node *next;
}
node;
//defining functions
node* create(int number);
node* insert(node *new_linked_list, int number);
void print(node *new_linked_list);
void delete_list(node *new_linked_list);
int main(void)
{
//create new linked list with function
node *new_linked_list = NULL;
//get input to update list
for (int i = 0; i < 10; i++)
{
int temp;
if (i == 0)
{
scanf(" %i", &temp);
printf("\n");
new_linked_list = create(temp);
continue;
}
//will insert new nodes in the linked lists
scanf(" %i", &temp);
printf("\n");
new_linked_list = insert(new_linked_list, temp);
}
//prints node number values out
print(new_linked_list);
//delete/free list
delete_list(new_linked_list);
}
//function will return a pointer to the first node in the list
node* create(int number)
{
node *firstnode = malloc(sizeof(node));
firstnode -> number = number;
firstnode -> next = NULL;
return firstnode;
}
//function that will update the linked list and return a pointer to the new head of the linked list
node* insert(node *new_linked_list, int number)
{
node* new_node = malloc(sizeof(node));
if (new_node == NULL)
{
return new_linked_list;
}
//new node will point to the old first node and updates new_nodes number
new_node -> number = number;
new_node -> next = new_linked_list;
//returns a pointer to the new first node
return new_node;
}
void print(node *new_linked_list)
{
//temporary node for reversal
node *trav = new_linked_list;
for (int i = 0; i < 10; i++)
{
printf("%i ",trav -> number);
trav = trav -> next;
if (i == 9)
{
printf("\n");
}
}
}
void delete_list(node *new_linked_list)
{
//base case: at null pointer
if (new_linked_list -> next == NULL)
{
//frees memory previously allocated to a pointer
free(new_linked_list);
return;
}
//else delete the rest of the list
else
{
delete_list(new_linked_list -> next);
}
}
Hi so I was experimenting with a linked list and came across a problem. My program leaks memory because I am not freeing the "new node". However, I'm confused on how to free it as it is being return to be used in main. How would I go about freeing "new node" while still being able to use it in the main function. Thank you for any help in advance.
The issue seems to be related to the recursive behaviour of 'delete_list'
It could be implemented like the following:
void delete_list(node *new_linked_list)
{
node *next;
while(new_linked_list != NULL)
{
next = new_linked_list->next;
free(new_linked_list);
new_linked_list = next;
}
}
Task is to create a linked list consisting of objects. User inputs data for each individual Node in the main and then the object is being passed to push, which creates the list.
The problem comes in the printList function, where the condition for a break is never met.
For some reason the line head = head->next doesn't do anything, as the address of next with every iteration remains the same.
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
Node *head = NULL;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
struct Node {
int oA;
char oAsd[30];
struct Node *next;
};
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->oA);
getchar();
if (!object->oA) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->oAsd, 30);
if (!(strcmp(object->oAsd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
tmp = object;
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}`
There are two major problems in your code:
You define struct Node both outside main and inside main
Here tmp = object; you copy the value of a pointer to another pointer but you really want to copy the value of a struct to another struct, i.e. *tmp = *object;.
Besides that - don't put head as a global variable.
So the code should be more like:
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
Node *head = NULL;
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->a);
getchar();
if (!object->a) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->asd, 30);
if (!(strcmp(object->asd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
*tmp = *object; // Copy the struct
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I wrote this to perform push and reverse operation on linked list but the push/reverse function is not working somehow. I don't know where the problem is, everything seems to be fine. Can someone help me out? I think there's a problem with the head of the linked list or the parameter of the functions. Do I need to declare a pointer to pointer as parameter?
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
struct node {
int data;
struct node *next;
};
typedef struct node NODE;
NODE *head1 = NULL;
int flag = 1;
int choice;
void push(NODE*);
void menu();
void reverse(NODE*);
void display(NODE*);
int main() {
do {
menu();
if (choice == 1) {
push(head1);
display(head1);
}
else if (choice == 2) {
reverse(head1);
display(head1);
}
else {
break;
}
} while (1);
}
void push(NODE *head) { //function to create the linked list
int choice1, flag = 1;
do {
NODE *new_node = (NODE*)malloc(sizeof(NODE*));
puts("Enter new node data:");
scanf("%d", &new_node->data);
if (!head) {
head = new_node;
head->next = NULL;
}
else {
new_node->next = head;
head = new_node;
}
puts("Do you want to continue? Press 1:");
fflush(stdin);
scanf("%d", &choice1);
if (choice1 != 1) {
flag = 0;
}
} while (flag);
}
void menu() {
puts("Enter 1 to push, 2 to reverse, anything else to exit:");
scanf("%d", &choice);
}
void reverse(NODE *head) { //function to reverse it
NODE *prev = NULL, *next = NULL;
NODE *current = head;
while (current) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
}
void display(NODE *head) {
NODE *temp = head;
puts("Status of the linked list:");
for (; temp; temp = temp->next) {
printf("%d=> ", temp->data);
}
puts("NULL");
}
There are many things wrong with this code. I'll start with a small snippet.
/* global */
NODE *head1 = NULL;
/* in main */
push(head1);
void push(NODE *head) { //function to create the linked list
int choice1, flag = 1;
do {
NODE *new_node = (NODE*)malloc(sizeof(NODE*));
puts("Enter new node data:");
scanf("%d", &new_node->data);
if (!head) {
head = new_node;
head->next = NULL;
}
push() is taking a pointer to NODE, allocating something and then assigning it to that pointer. this only modifies the local copy of the pointer in push() , leaving head1 unmodified. To modify head1, you either need to return a pointer or take a pointer to pointer.
That is either
void push(NODE** head)
or
NODE* push(NODE* head)
head1 = push(head1);
Also you are allocating sizeof(NODE*), the size of a pointer (typically 8 or 4 bytes). This should be sizeof(NODE).
I was having some confusion between ListNode and LinkedList. Basically my question was divided into 2 parts. For first part, I was supposed to do with ListNode. The function prototype as such:
int removeNode(ListNode **ptrHead, int index);
All function were working fine for the ListNode part. Then as for the second part, I was supposed to change the function above to this:
int removeNode(LinkedList *11, int index);
My code for part 1 which is working fine look like this:
int removeNode(ListNode **ptrHead, int index) {
ListNode *pre, *cur;
if (index == -1)
return 1;
else if (findNode(*ptrHead, index) != NULL) {
pre = findNode(*ptrHead, index - 1);
cur = pre->next;
pre->next = cur->next;
return 0;
}
else
return 1;
}
ListNode *findNode(ListNode *head, int index) {
ListNode *cur = head;
if (head == NULL || index < 0)
return NULL;
while (index > 0) {
cur = cur->next;
if (cur == NULL) return NULL;
index--;
}
return cur;
}
And here is my entire code for the part 2 which is not working:
#include "stdafx.h"
#include <stdlib.h>
typedef struct _listnode {
int num;
struct _listnode *next;
}ListNode;
typedef struct _linkedlist {
ListNode *head;
int size;
}LinkedList;
void printNode2(ListNode *head);
int removeNode2(LinkedList *ll, int index);
int main()
{
int value, index;
ListNode *head = NULL, *newNode = NULL;
LinkedList *ptr_ll = NULL;
printf("Enter value, -1 to quit: ");
scanf("%d", &value);
while (value != -1) {
if (head == NULL) {
head = malloc(sizeof(ListNode));
newNode = head;
}
else {
newNode->next = malloc(sizeof(ListNode));
newNode = newNode->next;
}
newNode->num = value;
newNode->next = NULL;
scanf("%d", &value);
}
printNode2(head);
printf("\nEnter index to remove: ");
scanf("%d", &index);
removeNode2(ptr_ll, index);
printNode2(head);
return 0;
}
void printNode2(ListNode *head) {
printf("Current list: ");
while (head != NULL) {
printf("%d ", head->num);
head = head->next;
}
}
int removeNode2(LinkedList *ll, int index) {
ListNode *head = ll->head;
if (head == index)
{
if (head->next == NULL)
{
printf("There is only one node. The list can't be made empty ");
return 1;
}
/* Copy the data of next node to head */
head->num = head->next->num;
// store address of next node
index = head->next;
// Remove the link of next node
head->next = head->next->next;
return 0;
}
// When not first node, follow the normal deletion process
// find the previous node
ListNode *prev = head;
while (prev->next != NULL && prev->next != index)
prev = prev->next;
// Check if node really exists in Linked List
if (prev->next == NULL)
{
printf("\n Given node is not present in Linked List");
return 1;
}
// Remove node from Linked List
prev->next = prev->next->next;
return 0;
}
When I try to run the part 2, the cmd just not responding and after a while, it just closed by itself and I have no idea which part went wrong. I was thinking am I in the correct track or the entire LinkedList part just wrong?
When I tried to run in debug mode, this error message popped up:
Exception thrown at 0x01201FD1 in tut.exe: 0xC0000005: Access violation reading location 0x00000000.
If there is a handler for this exception, the program may be safely continued.
Thanks in advance.
You say that you got the linked list to work wihen the list is defined via the head pointer only. In this set-up, you have to pass a pointer to the head pointer when the list may be updated, and just the head pointer when you only inspect the list without modifying, for example:
int removeNode(ListNode **ptrHead, int index);
ListNode *findNode(ListNode *head, int index);
Here, the head pointer is the handle for the list that is visible to the client code.
The approach with the list struct defines a new interface for the linked list. While the head node is enough, it might be desirable to keep track of the tail as well for easy appending or of the number of nodes. This data can be bundles in the linked list struct.
What that means is that the handling of the nodes is left to the list and the client code uses only the linked list struct, for example:
typedef struct ListNode ListNode;
typedef struct LinkedList LinkedList;
struct ListNode {
int num;
ListNode *next;
};
struct LinkedList {
ListNode *head;
ListNode *tail;
int size;
};
void ll_print(const LinkedList *ll);
void ll_prepend(LinkedList *ll, int num);
void ll_append(LinkedList *ll, int num);
void ll_remove_head(LinkedList *ll);
int main()
{
LinkedList ll = {NULL};
ll_append(&ll, 2);
ll_append(&ll, 5);
ll_append(&ll, 8);
ll_print(&ll);
ll_prepend(&ll, 1);
ll_prepend(&ll, 0);
ll_print(&ll);
ll_remove_head(&ll);
ll_print(&ll);
while (ll.head) ll_remove_head(&ll);
return 0;
}
There's also one difference: In the head-node set-up, the head node might be null. Here, the list cannot be null, it must exist. (Its head and tail members can be null, though.) Here the list is allocated on the stack, its address &ll must be passed to the functions.
In the linked list set-up, the distinction between modifying and read-only access is done via the const keyword:
void ll_print(const LinkedList *ll);
void ll_prepend(LinkedList *ll, int num);
In your example, you take a mixed approach with two independent structures, a head node and a list. That can't work, one single list is described by one struct, pick one.
The advantage to the linked list structure approach is that all required data like head, tail and size are always passed together to a function. You can also hide the implementation from the user by not disclosing the struct members, so that theb user can only work on pointers to that struct.
Finally, here's an example implementation of the above interface for you to play with:
void ll_print(const LinkedList *ll)
{
ListNode *node = ll->head;
while (node != NULL) {
printf("%d ", node->num);
node = node->next;
}
putchar('\n');
}
void ll_prepend(LinkedList *ll, int num)
{
ListNode *nnew = malloc(sizeof *nnew);
nnew->next = ll->head;
nnew->num = num;
ll->head = nnew;
if (ll->tail == NULL) ll->tail = ll->head;
ll->size++;
}
void ll_append(LinkedList *ll, int num)
{
ListNode *nnew = malloc(sizeof *nnew);
nnew->next = NULL;
nnew->num = num;
if (ll->tail == NULL) {
ll->tail = ll->head = nnew;
} else {
ll->tail->next = nnew;
ll->tail = nnew;
}
ll->size++;
}
void ll_remove_head(LinkedList *ll)
{
if (ll->head) {
ListNode *ndel = ll->head;
ll->head = ll->head->next;
ll->size--;
free(ndel);
}
}
There's nothing wrong when i built the program in both VS & codeblock. While, when i ran it, it either broke after i typed in the index number or just show letters infinitely...
#include<stdio.h>
#include<stdlib.h>
// list_node structure
typedef struct list_node{
int item;
struct list_node *next;
}ListNode;
//call functions that will be used
void printNode(ListNode *head);
int removeNode(ListNode **ptrhead, int index);
ListNode *findNode(ListNode *head, int index);
int main(){
int index,value;
ListNode *head=NULL;
ListNode *temp;
//build the list
printf("Enter a value:");
scanf("%d",&value);
do{
temp->item=value;
if(head==NULL){
head=(struct list_node *)malloc(sizeof(ListNode));
temp=head;
}
else{
temp->next=(struct list_node *)malloc(sizeof(ListNode));
temp=temp->next;
}
printf("Enter a value:");
scanf("%d",&value);
}while(value!=-1);
printf("Enter the index: ");
scanf("%d",&index);
// remove the node at the position indexed
// when I used debugger, I saw it didn't execute this step. Maybe there's something wrong with it....
removeNode(&head,index);
printNode(head);
return 0;
}
void printNode(ListNode *head){
if (head==NULL)
exit(0);
while(head!=NULL){
printf("%d",head->item);
head=head->next;
}
printf("\n");
}
ListNode *findNode(ListNode *head,int index){
if(head==NULL||index<0)
return NULL;
while(index>0){
head=head->next;
index--;
}
return head;
}
int removeNode(ListNode **ptrhead,int index){
ListNode *pre,*cur,*temphead;
temphead=*ptrhead;
if(findNode(temphead,index)!=NULL){
pre=findNode(temphead,index);
cur=pre->next;
temphead->next=cur;
return 0;
}
else
return -1;
}
prev=NULL;
cur=head;
/* traverse the list until you find your target */
while (cur != NULL && cur->id != search_id) {
prev=cur;
cur=cur->next;
}
/* if a result is found */
if (cur != NULL) {
/* check for the head of the list */
if (prev == NULL)
head=cur->next;
else
prev->next=cur->next;
/* release the old memory structure */
free(cur);
}
Whats up dude....I hope u will get it... :)
temp->item=value; - you're dereferencing temp when it's uninitialized. Undefined behavior, crash and burn.
In your loop,
temp->item=value;
No space has been allocated to temp. Hence, this will crash !!
if(head==NULL){
head=(struct list_node *)malloc(sizeof(ListNode));
temp=head;
Typically, you woud allocate a temp node and assign it to head as head = temp. Another point which is missing is when a new node is created, the next should be initialized to NULL as temp->next = NULL
In removeNode,
if(findNode(temphead,index)!=NULL){
pre=findNode(temphead,index);
pre will be pointing to the node to be removed, but temphead will still be pointing to head of the list. findNode will not modify the temphead. So tmphead->next = cur will modify the head always
int removeNode(ListNode **ptrhead,int index){
ListNode *pre,*cur;
if (index==-1)
return 1;
else if(findNode((*ptrhead),(index))!=NULL){
pre=findNode((*ptrhead),(index-1));
cur=pre->next;
pre->next=cur->next;
return 0;
}
else
return 1;
}
I modified the last part and addedtemp->next=NULLin the main function. this program can ran well now!