So this is a very simple program to create and display a linked list. Here I'm getting caught in the display loop, and I'm seeing infinite '2->2->2->...' on screen.
After debugging, I can see that my program ALWAYS goes into the if statement of insertNode() whereas it should only go there ONCE i.e. when the linked list is initialized.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node * next;
};
struct node * head = NULL;
struct node * curr = NULL;
void insertNode(struct node * temp2) {
if (head == NULL) {
head = temp2;
head->next = NULL;
}
else {
temp2->next = head;
head = temp2;
}
}
void display() {
curr = head;
while (curr->next != NULL)
{
printf("%d->",curr->data);
curr = curr->next;
}
}
void main() {
struct node * temp = (struct node *) malloc (sizeof(struct node));
temp->data = 5;
insertNode(temp);
temp->data = 6;
insertNode(temp);
temp->data = 1;
insertNode(temp);
temp->data = 2;
insertNode(temp);
display();
}
You should allocate and create new node for each data when inserting it in the linked list.
void main() {
struct node * temp = (struct node *) malloc (sizeof(struct node));
temp->data = 5;
insertNode(temp);
temp = malloc (sizeof(struct node));
temp->data = 6;
insertNode(temp);
temp = malloc (sizeof(struct node));
temp->data = 1;
insertNode(temp);
temp = malloc (sizeof(struct node));
temp->data = 2;
insertNode(temp);
display();
}
As you are using same node to add as multiple nodes, its making the circular list.
Your insertNode() looks ok.
You are setting next of temp2 to head, and then head to temp2. So in fact next node of temp2 is temp2, that's why you have infinite loop.
In you main you have one pointer to the temp and you continue inserting the same node and it ends up pointing to itself. You now have a circular list that's why you have an infinite loop.
You are getting an infinite loop because you only have one node. Doing temp->data = 5; and then temp->data = 6; does not create a new node. So when you add the same node into the list again, the next pointer in the node points to itself. So your while loop in display never terminates, because the next node is always the current node.
Related
I'm writing a program that creates a doubly linked list out of an array. Here's the code so far:
#include<stdio.h>
#include<stdlib.h>
struct Node {
int data;
struct Node *next;
struct Node *previous;
}
struct Node *create_dll_from_array(int array[], int x) {
int i;
struct Node *newNode, *temp, *head;
for (i=0; i<x; i++) {
newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = *(array+i);
if (i=0) {
head = newNode;
temp = newNode;
newNode->next = NULL;
newNode->previous = NULL;
}
else {
*** temp->next = (struct Node*) newNode->data;
newNode->next = NULL;
*** newNode->previous = (struct Node*) temp->data;
temp = newNode;
}
}
return head;
}
int main(){
int array[5] = {11,2,7,22,4};
struct Node* head;
head = create_dll_from_array(array,5);
return 0;
}
So in the lines with ***, I'm getting the error: warning: cast to pointer from integer of different size
I don't know whether the program itself actually works, just asking about those two lines and why they aren't working. Thanks!
How to fix casting a pointer to an integer?
Don't assign an int to a pointer and then the need for casting is gone.
Assign a pointer to a pointer.
// temp->next = (struct Node*) newNode->data;
temp->next = newNode;
You can improve on these things:
Always initialize your pointer with NULL. This will guard you against the pointer pointing to an invalid address.
Do not hard code the array size value. Calculate it.
In the if condition you have used assignment =. Change that to equality check ==. If you will not do this, your program will crash.
just asking about those two lines and why they aren't working
It is because, temp->next points to a memory location of type struct node. You cant assign it an integer value (as you were doing). I have reproduced your full code below some of your lines commented.
#include<stdio.h>
#include<stdlib.h>
struct Node {
int data;
struct Node *next;
struct Node *previous;
};
struct Node *create_dll_from_array(int array[], int x) {
int i;
// struct Node *newNode, *temp, *head;
struct Node *newNode= NULL, *temp=NULL, *head=NULL;
for (i=0; i<x; i++) {
newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = *(array+i);
// if (i=0) { Its wrong
if (i==0) {
head = newNode;
temp = newNode;
newNode->next = NULL;
newNode->previous = NULL;
}
else {
// temp->next = (struct Node*) newNode->data; // issue
temp->next = (struct Node*) newNode;
newNode->next = NULL;
// newNode->previous = (struct Node*) temp->data; //issue
newNode->previous = (struct Node*) temp; //issue
temp = newNode;
}
}
return head;
}
int main(){
// int array[5] = {11,2,7,22,4};
int array[] = {11,2,7,22,4};
struct Node* head;
// head = create_dll_from_array(array,5);
head = create_dll_from_array(array,sizeof(array)/sizeof(*array));
return 0;
}
Few more optimization that you can do is that inside your create_dll function, the if condition is hit only for the first time. You can move that to else condition and make your else condition your if condition
I have been having trouble with this linked list specifically it seems like my head pointer is not linking to the rest of my list and I am confused as to why it is not. Where I insert my head pointer by pointer by reference it is not connected to the linked list referenced in main. unless the list is not linked together in the main function and I am missing something.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int number;
struct node * next;
} Node;
typedef Node * Nodeptr;
void printlist (Node * head){
Node * n = head;
while(n != NULL){
printf("%d\n",n ->number);
n = n ->next;
}
}
void sumlist (Node * head){
Node * n = head;
int sum;
while(n != NULL){
sum = n ->number +sum;
n = n ->next;
}
printf("the total of all numbers in this list is %d",sum);
}
search(head){
}
int main(){
int i =0;
Nodeptr head=NULL;
if((head = malloc(sizeof(Node))) == NULL)
return 0;
head->number =rand()%50+50;
head ->next = malloc(sizeof(Node));
int n;
Nodeptr newnode = NULL;
for(n=0;n<99;n++)
{
newnode = malloc(sizeof(Nodeptr));
newnode->number = rand()%50+50;
newnode->next =NULL;
head -> next = newnode;
}
printlist(head);
sumlist(head);
return 0;
}
The error is that you are linking everything as next of head
head -> next = newnode;
You need to use a pointer that gets updated:
Nodeptr newnode = NULL;
Nodeptr last = head;
for(n=0;n<99;n++)
{
newnode = malloc(sizeof(Nodeptr));
newnode->number = rand()%50+50;
newnode->next =NULL;
last -> next = newnode;
last = last->next;
}
You should also change this:
head ->next = malloc(sizeof(Node)); // otherwise you will lose this element.
into
head ->next = NULL;
You execute these steps in a loop:
newnode = malloc(sizeof(Nodeptr));
newnode->number = rand()%50+50;
newnode->next =NULL;
head -> next = newnode;
You are setting the newnode->next to point to null, and head->next to point to newnode.
This means, each time through the loop your head gets a new next, and that's it.
Effectively, each time you pass through the loop you drop the previous newnode on the floor, and link to a new one. At the end, you'll have head pointing to 1 node, and you'll have 98 nodes dropped on the floor that you can't reach.
You need to either maintain a "tail" pointer, or a copy of "head", and set head or tail or something to the most recent value of newnode. Then, you can set tail->next = newnode; tail = newnode; which will continually extend your list, rather than overwriting the same head->next each time.
I am trying to add a new node to the end of a linked list, I am able to add something, but when I print it out the node has a value of '0'. I thought this might be happening because I may have neglected to initialise a variable somewhere, or forgot to allocate memory said variable. but I can't get it to work.
Here is my source code:
my Linked List/struct:
#include<stdio.h>
typedef char DATA;
struct Node {
DATA d;
struct Node *next;
};
my printList function:
void printList(struct Node **head) {
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *temp;
temp = *head;
printf("Linked list:");
while (temp->next != NULL) {
printf( " \n %d ", temp->d);
temp = temp->next;
}
printf("\n");
}
my insertNodeAtEnd to end function:
// inset data at end
void insertNodeAtEnd(struct Node *head) {
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *currentNode, *temp;
temp = newNode;
currentNode = newNode;
printf("Enter a Node to insert at the end of the list \n");
scanf("%s", &newNode->d);
newNode->next = NULL;
if (head == NULL) {
head = newNode;
currentNode = newNode;
} else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}
and my main():
int main() {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
struct Node *head = newNode;
struct Node *temp = newNode;
head->d = 1;
int i = 0;
printf("Enter 3 numbers");
for (i = 0; i < 3; i++) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
scanf("%d", &temp->d);
temp->next = newNode;
temp = temp->next;
}
insertNodeAtEnd(head);
printList(&head);
return 0;
sorry for any messy code, I'm still reasonably new at this
Well, you have a couple of mistakes. Firstly, you need to add
temp->next = NULL;
before line insertNodeAtEnd(head);. The reason your code might work without this line is probably because your compiler initializes the pointer to NULL by default. For example in GCC you program is crashing without that line.Second problem is that you are defyning DATA type as a char, but reading it as int. It may cause crashing your application if processor working with big-engian addresses. You should change it to
typedef int DATA;
and also change
scanf("%s", &newNode->d);
to
scanf("%d", &newNode->d);
After that, change
while(temp->next!=NULL)
to
while(temp!=NULL)
because otherwise you are missing the last element. Then, you need to reorder a loop a little bit. This is the full working code with all fixes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef int DATA;
struct Node
{
DATA d;
struct Node *next;
};
void printList(struct Node **head)
{
struct Node *newNode;
struct Node *temp;
temp = *head;
printf("Linked list:");
while(temp!=NULL)
{
printf( " \n %d ", temp->d);
temp = temp->next;
}
printf("\n");
}
// inset data at end
void insertNodeAtEnd(struct Node **headPointer)
{
struct Node *head = *headPointer;
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *currentNode, *temp;
temp = newNode;
currentNode = newNode;
printf("Enter a Node to insert at the end of the list \n");
scanf("%d", &newNode->d);
newNode->next = NULL;
if(head == NULL)
{
head = newNode;
currentNode = newNode;
}
else
{
temp = head;
while(temp->next!= NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
*headPointer = head;
}
int main()
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
struct Node *head = newNode;
struct Node *temp = newNode;
head->d = 1;
int i = 0;
printf("Enter 3 numbers: ");
for(i = 0; i < 3; i++)
{
if(i){
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
temp->next = newNode;
temp = temp->next;
scanf("%d", &temp->d);
}else{
scanf("%d", &temp->d);
}
}
temp->next = NULL;
insertNodeAtEnd(&head);
printList(&head);
return 0;
}
UPDATE
I added a two more fixes. as #BLUEPIXY pointed out, there are a few more OP's mistakes. I've already spotted them, but I didn't fix it because they were not essential to what causes OP's problem. But, anyway, the mistakes are following:
Firstly, if the list is empty, function insertNodeAtEnd will not update pointer to the list because you are passing pointer to head of the list instead of pointer of a pointer to the head. It can be fixed by adding ** to the function argument type.
Secondly, you don't need to allocate memory while printing a list. You obviously just copied the code to each function, even to functions which doesn't require inserting nodes (like printList).
The above script is updated script including these two fixes.
#include <stdio.h>
#include <conio.h>
struct node
{
int data;
struct node* next;
};
int main()
{
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = (struct node*)malloc(sizeof(struct node));
second = (struct node*)malloc(sizeof(struct node));
third = (struct node*)malloc(sizeof(struct node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
struct node* new1;
struct node* temp1;
temp1 = head;
while(temp1->next != NULL)
{
temp1 = temp1->next;
}
new1 = (struct node*)malloc(sizeof(struct node));
temp1->next = new1;
new1->data = 5;
new1->next = NULL;
while(temp1 != NULL)
{
printf("%d ",temp1->data);
temp1 = temp1->next;
}
return 0;
}
This is the program for inserting a node at the end of linked list. The expected output is = 1 2 3 5, 5 is the new node's value here. But the current output is = 3 5. I don't know where am I wrong. Any answer will be appreciated.
while(temp1->next != NULL)
{
temp1 = temp1->next;
}
After this loop your temp1 is at the end of the list and you are adding a node at the end of the list.
Now you are trying to print from temp1 obviously you will get only 2 nodes new one and the one before it.
If you want the whole list print from head.
Just before printing after adding your new node. Point temp1 to head.
temp1 = head;
while(temp1 != NULL)
{
printf("%d ",temp1->data);
temp1 = temp1->next;
}
One thing to remember when using something like you did to get to the end of the list: If you just say third->next = first, then it will go on forever. This is something to watch out for, and also something you may want to play with. Maybe consider adding a list_size integer somewhere so that infinite looping does not happen.
My program keeps on crashing. I think there's a problem in my logic. Please help! Thanks!
struct node{
int data;
struct node *prev,*next;
} *head = NULL;
void insert(){
struct node* temp = (struct node*) malloc (sizeof (struct node*));
int value;
printf("Enter an element");
scanf("%d",&value);
temp -> data = value;
temp -> next = NULL;
temp -> prev = NULL;
if(value < head -> data || head == NULL){
temp -> next = head -> next;
head = temp;
return;
}
while(head->next != NULL && value > head -> next -> data)
head = head -> next;
temp -> next = head ->next->prev;
head -> next = temp -> prev;
while (head -> prev != NULL)
head = head -> prev;
}
Try this:
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *prev,*next;
} *head = 0;
void insert(int value){
struct node* temp = (struct node*) malloc (sizeof (struct node));
//int value;
//printf("Enter an element");
//scanf("%d",&value);
temp -> data = value;
temp -> next = 0;
temp -> prev = 0;
if(head == 0) {
// no head, make temp the head
head = temp;
} else if(value > head->data) {
// put temp in front of the head
temp->next = head;
head->prev = temp;
head = temp;
} else {
// put temp after the head
struct node *this = head;
struct node *prev = 0;
while(this && this->data > value) {
prev = this;
this = this->next;
}
temp->next = this;
temp->prev = prev;
prev->next = temp;
if(this) {
this->prev = temp;
}
}
}
int main() {
insert(1);
insert(3);
insert(4);
struct node *t = 0;
for(t = head; t; t = t->next) {
printf("%d\n", t->data);
}
}
This one compiles and sorts in descending value. Note I commented out your scanf
and made insert take a parameter.
the space you malloc is not enough.
change
struct node* temp = (struct node*) malloc (sizeof (struct node*));
to
struct node* temp = (struct node*) malloc (sizeof (struct node));
As a start, think about these two lines and what happens if head == NULL:
if(value < head->data || head == NULL){
temp->next = head->next;
Specifically what is head->next?
There are two core problems I see.
You are not allocating sufficient space for a node struct. sizeof(struct node *) returns the size of a node pointer, not a node. This:
struct node* temp = (struct node*) malloc (sizeof (struct node*));`
... should be this:
struct node* temp = (struct node*) malloc (sizeof (struct node));
Be careful with pointers:
if (value < head -> data || head == NULL)
... what is the value of head->data if you haven't initialized head? (e.g. it is still NULL). Your program will fetch data from address NULL with an offset for field data. Address NULL is not valid / is part of protected memory space, your OS won't like this :).
You should first check if head is NULL. If it is, then you can't reference fields of head as they are invalid (in any situation). Be careful with multi-part conditional expressions to check for struct pointer NULL presence prior to subsequent parts that reference struct fields, also.