#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
static int COUNT = 1;
typedef struct node NODE;
struct node
{
int data;
NODE *next;
};
NODE *START = NULL;
NODE *create_node() {
NODE *n = malloc(sizeof(NODE));
n->data = 0;
n->next = NULL;
return n;
}
void insert_at_beginning() {
NODE *n, *temp;
n = create_node();
printf("Enter a number: ");
scanf("%d",&n->data);
if(START == NULL) {
START = n;
} else {
temp = START;
START = n;
n->next = temp;
}
COUNT++;
printf("Successfully Inserted!\n");
}
void insert_at_a_position() {
int position, count;
NODE *n, *temp, *t;
printf("Enter position at which you want to insert: ");
scanf("%d", &position);
if(COUNT<position) {
printf("Out of Bound! Please try again.\n");
} else
{
count = 1;
n = create_node();
printf("Enter a number: ");
scanf("%d",&n->data);
temp = START;
while(count != position) {
count++; //To stoping the variable at given position
t = temp; //Getting Previous node where we will set link to n
temp = temp->next; //getting next element whose link will be attached to n to form complete linked list
}
n->next = temp;
t->next = n;
COUNT++;
printf("Successfully Inserted!\n");
}
}
void insert_at_end() {
NODE *n, *temp;
temp = START;
n = create_node();
printf("Enter a number: ");
scanf("%d", &n->data);
while(temp!=NULL) {
printf("I am here!");
temp = temp->next;
}
temp->next = n;
COUNT++;
printf("Successfully Inserted!\n");
}
void display() {
NODE *temp;
temp = START;
while (temp!=NULL)
{
printf("%d", temp->data);
temp = temp->next;
}
}
int main() {
int ch;
printf("1.Insert at beginning\n2.Insert at mid\n3.Insert at end\n4.Delete from beginning\n5.Delete from position\n6.Delete from end\n7.Display");
printf("\nEnter your choice: ");
scanf("%d", &ch);
while (ch!=0)
{
switch(ch) {
case 1:
insert_at_beginning();
break;
case 2:
insert_at_a_position();
break;
case 3:
insert_at_end();
break;
case 4:
display();
break;
default:
printf("Wrong Choice!!");
}
printf("Enter Your Choice: ");
scanf("%d",&ch);
}
return 0;
}
insert_at_beginning and insert_at_end is working perfectly but insert_at_end and display function is showing problem
In display function: Program goes in infinite loop
In insert_at_end: Program goes through while loop (i.e., printing "I am here" node number of time) but then it terminates abruptly without assigning the value in the given position.
For starters it is a bad idea to declare the initial pointer to nodes as a global variable and when function depends on global variables.
Also it is unclear why the static variable COUNT is initialized by 1 instead of 0 when initially the list is empty.
static int COUNT = 1;
It should be initialized by zero
static int COUNT = 0;
insert_at_beginning and insert_at_end is working perfectly
You are wrong. The function insert_at_end is invalid.
void insert_at_end() {
NODE *n, *temp;
temp = START;
n = create_node();
printf("Enter a number: ");
scanf("%d", &n->data);
while(temp!=NULL) {
printf("I am here!");
temp = temp->next;
}
temp->next = n;
COUNT++;
printf("Successfully Inserted!\n");
}
For example the function can be called when the list is empty that is when the pointer START is equal to NULL. In this case the pointer START is not changed in the function.
Moreover even if the pointer START is not equal to NULL then after this loop
while(temp!=NULL) {
printf("I am here!");
temp = temp->next;
}
the pointer temp is equal to NULL. So the next statement
temp->next = n;
invokes undefined behavior.
The function can be written at least the following way
void insert_at_end() {
NODE *n;
n = create_node();
printf("Enter a number: ");
scanf("%d", &n->data);
if ( START == NULL )
{
START = n;
}
else
{
NODE *temp = START;
while ( temp->next !=NULL )
{
printf("I am here!");
temp = temp->next;
}
temp->next = n;
COUNT++;
printf("Successfully Inserted!\n");
}
}
As for the function insert_at_a_position then there is a confusion relative to the global variable COUNT. As I pointed out initially when the list is empty COUNT is equal to 1. So a valid position can be less than COUNT. Take into account that the user can enter for example the value of position equal to 0.
So for example this if statement
if(COUNT<position) {
printf("Out of Bound! Please try again.\n");
} else
should be rewritten like
if ( !( position < COUNT ) ) {
printf("Out of Bound! Please try again.\n");
} else
Also when the user will enter 0 then this loop
count = 1;
//...
while(count != position) {
//...
can invoke undefined behavior.
And again if the list is empty that is START is equal to NULL then START is not changed in the function.
Also if the user entered the position equal to 1 then in this case the while loop will not executed. On this case the pointer t has indeterminate value because it was not initialized outside the loop. So this statement
t->next = n;
again invoke undefined behavior.
The function can be defined the following way
void insert_at_a_position() {
int position;
printf("Enter position at which you want to insert: ");
scanf("%d", &position);
if( !( position < COUNT ) ) {
printf("Out of Bound! Please try again.\n");
} else
{
NODE *n = create_node();
printf("Enter a number: ");
scanf("%d",&n->data);
NODE *temp = START;
NODE *prev = START;
while( position-- != 0 )
{
prev = temp;
temp = temp->next;
}
n->next = temp;
if ( prev == NULL ) START = n;
else prev->next = n;
COUNT++;
printf("Successfully Inserted!\n");
}
}
You are dereferencing a NULL pointer.
while(temp!=NULL) {
printf("I am here!");
temp = temp->next;
}
temp->next = n; // temp is NULL here!!
You can change the loop condition to:
while (temp->next != NULL) {
But before you do that, you should check that temp is not NULL:
temp = START;
if (temp == NULL) {
insert_at_beginning();
return;
}
Aside: it is more standard to just write:
if (!temp)
than
if (temp == NULL)
Related
#include <stdio.h>
#include <stdlib.h>
/*EVERYTHING WORKS EXCEPT FOR INITIAL -1*/
// Implementing a Node Structure - This represents a node of data
typedef struct _listnode
{
int item; // Data
struct _listnode *next; // Linkage
} ListNode;
// Core Functions of a Linked List
void printList(ListNode *head);
ListNode* findNode(ListNode *head, int index);
int insertNode(ListNode **ptrHead, int index, int value);
void removeNode(ListNode **ptrHead, int index);
int main()
{
// Instantiate a Linked List
ListNode *head = NULL, *temp;
/*
head is a pointer variable that will eventually point to the firstNode.
temp is a pointer variable that points to the lastNode. This is used in from Linked List functions.
*/
int num_to_store;
printf("Enter an Integer to Store (-1 to end):\n");
scanf("%d", &num_to_store);
while (num_to_store != -1)
{
// Initialize a Linked List
if (head == NULL)
{
head = malloc(sizeof(ListNode));
temp = head;
}
else
{
temp->next = malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = num_to_store;
printf("Enter an Integer to Store (-1 to end):\n");
scanf("%d", &num_to_store);
}
temp->next = NULL;
// Menu-Driven Application
int user_choice, index, value, *p, option_3;
puts("");
printf("----------------\n 1: printList()\n 2: findNode()\n 3: insertNode()\n 4: removeNode()\n-1: End\n----------------\n");
scanf("%d", &user_choice);
while (user_choice != -1)
{
switch(user_choice)
{
case 1:
printList(head);
break;
case 2:
printf("Enter index to search:\n");
scanf("%d", &index);
p = findNode(head, index);
if (p != NULL) printf("Node Item: %d\n", *p);
break;
case 3:
printf("Enter index to insert:\n");
scanf("%d", &index);
printf("Enter value to insert:\n");
scanf("%d", &value);
option_3 = insertNode(&head, index, value);
if (option_3 == 0) printf("NODE INSERTED!\n");
break;
case 4:
printf("Enter index to remove:\n");
scanf("%d", &index);
removeNode(&head, index);
break;
}
// Prompt User to Make Another Selection
puts("");
printf("----------------\n 1: printList()\n 2: findNode()\n 3: insertNode()\n 4: removeNode()\n-1: End\n----------------\n");
scanf("%d", &user_choice);
}
return 0;
}
void printList(ListNode *head)
{
// Linked List is Empty
if (head == NULL)
{
printf("LINKED LIST IS EMPTY!\n");
}
// Linked List is Not Empty
else
{
printf("LINKED LIST: ");
while (head != NULL)
{
printf("%d ", head->item);
head = head->next;
}
puts("");
}
}
ListNode* findNode(ListNode *head, int index)
{
// Linked List is Empty or Index is Invalid
if (head == NULL || index < 0)
{
printf("INVALID!\n");
return NULL;
}
// Linked List is not Empty, Check if Index > len(Linked List)
else
{
while (index > 0)
{
head = head->next;
if (head == NULL)
{
printf("INVALID!\n");
return NULL;
}
index--;
}
printf("INDEX FOUND!\n");
return head;
}
}
int insertNode(ListNode **ptrHead, int index, int value)
{
ListNode *cur, *pre;
// Linked List is Empty || Insert at Index 0
if ((*ptrHead) == NULL || index == 0)
{
cur = *ptrHead;
*ptrHead = malloc(sizeof(ListNode));
(*ptrHead)->item = value;
(*ptrHead)->next = cur;
return 0;
}
// Insert in the Middle
else
{
pre = findNode(*ptrHead, index-1);
if (pre != NULL)
{
cur = pre->next; // This is temporary
pre->next = malloc(sizeof(ListNode)); // L connects to nN
pre->next->item = value;
pre->next->next = cur; // nN connects to R
}
return 0;
}
return -1;
}
void removeNode(ListNode **ptrHead, int index)
{
ListNode *cur, *pre;
// Linked List is Empty
if ((*ptrHead == 0) || index < 0)
{
printf("INVALID!\n");
}
// Remove firstNode
else if (index == 0)
{
cur = findNode(*ptrHead, index);
*ptrHead = cur->next;
free(cur); // Unallocate the memory
}
// Remove Middle
else
{
pre = findNode(*ptrHead, index-1);
cur = findNode(*ptrHead, index);
pre->next = cur->next;
cur->next = NULL;
}
}
Hi all, I am writing a Linked List program in C with the 4 core functions. The functions and everything else works except for when I compile the code and type -1. The program exits. I wonder what is wrong. I tried debugging on code::blocks but nothing showed up.
What am I trying to achieve?
Create a Linked List with no nodes.
Code the 4 core functions of a Linked List (insert/remove/print/search).
What have I tried?
Scattering printf() statements to debug.
Checked on stackoverflow for similar problems.
Viewed the code on geeksforgeeks.
Any idea the cause of the problem might be? And any possible solutions for this type of problem?
When you type -1, the whole while (num_to_store != -1) loop will be skipped, and temp will remain uninitialized, that will make temp->next = NULL; invoke undefined behavior.
I am supposed to do an assignment in C programming language. It includes linked lists and reading user input from the console.
The user inputs numbers into the console, for example ( 1 3 5 7 0 ), which are added, one by one, to the beginning of the linked list. 0 marks the end of the transition. This is what the linked list should look like after the first part: 7 5 3 1
I need to code two different functions that will delete different elements of the linked list.
First function deletes all elements from the list that have the value that you input, and second function deletes the element on the position that the user inputs, if it exists.
At the end, you should print the list.
I've written the the first function correctly, and I am sure about it, with the second function (the one that deletes elements on a certain position) I had some trouble. I made a simple function that counts how many nodes are there in total, so if someone puts a number larger than the amount of nodes, a message would pop up. I also used that function to make a for loop and used it as a limit when searching for the element on a certain position, if that makes any sense. The program also won't print anything, I have no idea why.
typedef struct Element Element;
struct Element
{
int number;
Element *next;
};
Element *addnewN(int number)
{
Element *newN = (Element*)malloc(sizeof(Element));
newN->number = number;
newN->next = NULL;
return newN;
}
Element *add_on_beginning(Element *head, Element *newN)
{
newN->next = head;
return head;
}
Element* delete_value(Element* head, int value)
{
Element *before = NULL;
Element *temp = head;
Element *newNhead = head;
while(temp != NULL)
{
if(temp->number == value)
{
if(before == NULL)
{
newNhead = temp->next;
free(temp);
temp = newNhead;
}
else
{
before->next = temp->next;
free(temp);
temp = before->next;
}
}
else
{
before = temp;
temp = temp->next;
}
}
return newNhead;
}
int counter(Element *head)
{
int count = 0;
Element *temp = head;
while(temp != NULL)
{
count++;
temp = temp->next;
}
return count;
}
Element* delete_on_position(Element* head, int position)
{
int limit = counter(head);
Element *temp = head;
Element *newNhead = head;
Element *before = NULL;
if(position > limit)
{
printf("Error.\n");
}
for(int i = 0; i < limit; i++)
{
if(position == 0)
{
newNhead = temp->next;
free(temp);
temp = newNhead;
}
else if(position == i)
{
before->next = temp->next;
free(temp);
temp = before->next;
}
else
{
before = temp;
temp = temp->next;
}
}
return head;
}
void printElement(Element *element)
{
printf("%d ", element->number);
}
void printList(Element *head)
{
Element *temp = head;
while(temp != NULL)
{
printElement(temp);
temp = temp->next;
}
}
void menu()
{
printf("\t MENU \n");
printf("1. Delete all elements from the list that have the value that
you input.\n");
printf("2. Delete the element on the position, if it exists.\n");
printf("3. Print the list. \n");
printf("4. Exit \n");
}
int main()
{
Element *head = NULL;
int i = 0;
int arr[1000];
char temp;
int x;
int y;
printf("Input the numbers you want: \n");
while(temp != '\n')
{
scanf("%d%c", &arr[i], &temp);
if(arr[i] == 0)
{
break;
}
head = add_on_beginning(head, addnewN(arr[i]));
i++;
}
menu();
while(1)
{
scanf("%d", &x);
switch(x)
{
case 1:
{
scanf("%d", &y);
head = delete_value(head, y);
break;
}
case 2:
{
scanf("%d", &y);
head = delete_on_position(head, y);
break;
}
case 3:
{
printList(head);
break;
}
case 4:
{
return 0;
}
}
}
return 0;
}
What you are supposed to get would be for example:
Input: 2 4 5 8 5 0 (in one line), and in one line each:
2
2
1
5
3
Output: 2 8
When debugged, the code does not show any errors.
add_on_beginning is not returning the correct value. It should return the node that was added, since it's the new head of the list. Nothing else will work correctly because of that, because head will always be NULL.
Element *add_on_beginning(Element *head, Element *newN)
{
newN->next = head;
return newN;
}
I wrote a program to perform singly linked list operation insert at a particular position now there is no nodes at the moment , when I give the the input: 3 to the question enter the position to be inserted it shows runtime error
void insert_pos()
{
struct node * temp, *loc;
int item,pos,len;
printf("enter the position to be insertd :");
scanf("%d", &pos);
if (pos == 1)
{
insert_beg();
}
else
{
len = length();
if (start == NULL)
{
insert_beg();
}
else if (pos > len)
{
insert_end();
}
else
{
newnode = (struct node *)malloc(sizeof(struct node));
printf("enter the data :");
scanf("%d", &item);
newnode->data = item;
int i;
temp = start;
loc = temp->next;
for (i = 1; i < pos - 1; i++)
{
temp = temp->next;
loc = loc->next;
}
temp->next = newnode;
newnode->next = loc;
}
}
}
int length()
{
int k = 1;
struct node * temp;
while (temp->next != NULL)
{
temp = temp->next;
k++;
}
return k;
}
out put
1.insert # beg
2.insert # end
3.insert # perticular pos
4.display
5.exit
enter your option :3
enter the position to be inserted :3
now a window pops up saying debug error
pls help me with it
the problem was here the temp was Uninitialized
int length()
{
int k = 1;
struct node * temp;
while (temp->next != NULL)
{
temp = temp->next;
k++;
}
return k;
}
the fix was to assign temp = start;
corrected program
int length()
{
int k = 1;
struct node * temp;
temp=start; // start is a global variable
while (temp->next != NULL)
{
temp = temp->next;
k++;
}
return k;
}
thanks every one for the tips !!!
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void Insert();
void DisplayList();
struct Student
{
char Name[10];
int Marks;
struct Student *Next;
} *Start;
int main()
{
Start = NULL;
int Choise;
while (1)
{
printf("enter number to choose ");
scanf_s("%d", &Choise);
switch (Choise)
{
case 1:
Insert();
break;
case 3:
DisplayList();
break;
default:
printf("Incorrect assignment Press relevant key :");
}
}
}
void Insert()
{
struct Student *Temp, *current=NULL;
Temp = (struct Student *) malloc(sizeof(struct Student));
printf("Enter Name Of Student");
scanf_s("%s",&Temp->Name);
printf("Enter Marks Of Student");
scanf_s("%d", &Temp->Marks);
Temp->Next = NULL;
if (Start == NULL)
{
Start = Temp;
Temp->Next = NULL;
}
else
current = Start;
while (current->Next != NULL)
{
current = current->Next;
current->Next = Temp;
}
}
void DisplayList()
{
struct Student *current, *Temp;
current = Start->Next;
if (Start == NULL)
{
printf("No Element in the list");
}
else
{
for (current = Start; current != NULL; current = current->Next)
{
printf("The List are\n");
printf_s("%d",current->Marks);
}
}
this is a Program written for single linked list.when i display the list it give only one element in the list. Whenever i am trying to print the elements of the linked list, it gives the output only one element
what mistake i do please help?
change
else
current = Start;
while (current->Next != NULL)
{
current = current->Next;
current->Next = Temp;
}
to
else {
current = Start;
while (current->Next != NULL)
{
current = current->Next;
}
current->Next = Temp;
}
and
scanf_s("%s", Temp->Name, sizeof(Temp->Name)); //remove & and add size(see Amnon's answer)
When using scanf_s which is the safe version of scanf, you are expected to pass not only the address of the buffer but also its size as the next parameter, i.e.:
scanf_s("%s", Temp->Name, _countof(Temp->Name));
You can read more about it in http://msdn.microsoft.com/en-us/library/w40768et.aspx
The other issue with the code is that you're initializing current with NULL but then trying to access its Next field.
Change the code here:
else
current = Start;
while (current->Next != NULL)
{
current = current->Next;
current->Next = Temp;
}
to this:
else {
current = Start;
while (current->Next != NULL)
{
current = current->Next;
}
current->Next = Temp;
temp->next=NULL;
}
you forget to add NULL at next pointer and therefore you are getting only single output.
I wrote a program that inserts nodes into a linked list in descending order.But whenever I test my code with numbers 12,14,13,19,7 in this order.Whenever I entered 7 I took 7 is already in the list.But as easily seen 7 is not in the list before I inserted.After give this error,if I choose print option by typing 2 my program entered in an infinite loop.I can not see my mistake and I am very confused.
#include <stdio.h>
#include <stdlib.h>
struct node {
int content;
struct node* nextLink;
};
typedef struct node NODE;
void print (NODE*);
int insertNode (NODE** head, int x);
int main (void)
{
int num, choice;
NODE* head;
head = NULL;
do {
printf("\nPlease press 1 to insert or press 2 to print or press 0 to exit\n");
scanf("%d", &choice);
switch (choice) {
case 0:
return 0;
break;
case 1:
printf("Enter an integer to insert into the linkedlist: ");
printf("\n");
scanf("%d", &num);
insertNode(&head, num);
break;
case 2:
print(head);
break;
default:
printf("You entered an invalid number\n");
return 0;
break;
}
} while (choice == 1 || choice == 2);
return 0;
}
int insertNode (NODE** head, int i)
{
NODE* newNode;
newNode = (NODE*)malloc(sizeof(NODE));
newNode->content = i;
NODE* temporary = *head;
newNode->nextLink = NULL;
if ((*head == NULL) || ((*head)->content) < i) {
*head = newNode;
(*head)->nextLink = temporary;
}
else {
do {
if (((temporary->content) > i) && ((temporary->nextLink->content) < i)) {
newNode->nextLink = temporary->nextLink;
temporary->nextLink = newNode;
return;
}
else if (temporary->content == i) {
printf("To be inserted value is already in the list\n");
return;
}
temporary = temporary->nextLink;
} while (temporary->nextLink != NULL);
if (temporary->content == i) {
printf("To be inserted value is already in the list\n");
return;
}
temporary->nextLink = newNode;
}
return 0;
}
void print (NODE* head)
{
if (head == NULL) {
printf("\nLinkedList is empty \n");
}
while (head != NULL) {
printf("%d ", head->content);
head = head->nextLink;
}
}
I compiled it and ran it and it seemed to work fine except for one thing. insertNode is defined to return an int, yet 3 of the return statements are void returns. To get it to compile, I changed them to return 0;. If you were able to compile and run it as is, then it could be the stack was getting destroyed by the inconsistent returns.
Your code won't work, if the first two values to be inserted are in descending order. It would give segmentation fault.
For the insertion of 2nd element you need to be careful
So after if condition
else if (temporary->content > i && temporary->nextLink==NULL)
(*head)->nextLink = newNode;
Your code is doing too much. If you code it differently, there are no special cases (such as insert at the top, insert at the tail of the list).
int insertNode (NODE **head, int val)
{
NODE *newnode;
for ( ; *head; head = &(*head)->nextLink) {
if ( (*head)->content == val) {
printf("To be inserted value (%d)is already in the list\n", val);
return 0;
}
if ( (*head)->content > val) break;
}
newnode = malloc(sizeof *newnode); // Maybe check return here ;-)
newnode->content = val;
newnode->nextLink = *head;
*head = newnode;
return 1;
}