Unexpected output in a linked list using C - singly-linked-list

I've just started learning C and am fairly a beginner.
Today in school we learned linked list and I was able to put up a code...which thankfully is running without errors.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
}*head;//*temp;
void create(struct node **h,int num)
{
int i;
struct node *temp=*h;
for(i=0;;i++)
{
if(i>=num)
break;
temp->data=i;
temp->next=malloc(sizeof(struct node));
temp=temp->next;
}
temp->next=NULL;
}
void display(struct node **h)
{
struct node *temp=*h;
while(temp->next!=NULL)
{
printf("%d->",temp->data);
temp=temp->next;
}
printf("\b\b \b\b");
}
void append_end(struct node **h,int val)
{
struct node *temp=*h,*temp1;
//printf("'%d'",val);
while(temp->next!=NULL)
temp=temp->next;
temp1=malloc(sizeof(struct node));
temp1->data=val;
temp1->next=NULL;
temp->next=temp1;
}
void free_list(struct node **h)
{
struct node *temp=*h,*tail;
while(temp->next!=NULL)
{
tail=temp;
temp=temp->next;
free(tail);
}
h=NULL;
}
int main()
{
head=malloc(sizeof(struct node));
int i,num;
scanf("%d",&num);
create(&head,num);
//display(&head);
append_end(&head,5);
append_end(&head,6);
display(&head);
/*temp=head;
while(temp->next!=NULL)
temp=temp->next;
printf("%d",temp->data);*/
free_list(&head);
return 0;
}
The expected output should be
0->1->2->3->5->6
for input of 4
But instead I'm getting
0->1->2->3->(some garbage value)->5
I'll be glad if someone could point out my error(s), and/or link to any article that might help me in understanding the topic clearly.
Thanks in advance.

I've refactored your code. You can see it here: http://ideone.com/nZ55i
Your code was ugly, so I tweaked it into my own style. I suggest you find a style you like, that's easy for you to read.
Moved declaration of head into main method (used to be a global variable)
Functions that took pointer-to-pointer types for no reason have been modified to take pointers.
You used malloc(sizeof(struct node)) in at least 3 places, so I just up and made a function that does it for you.
Added a typedef to the declaration of the node struct, you can declare instances of it now with just node derp;
create function uses a for loop with an empty condition and a break, refactored to use a proper for loop with no break
The garbage value was caused by a bug in your create function that prevented it from writing the value to the last node it created. To fix it, I moved stuff around so it always assigns the data field but doesn't allocate a new node if it's at the end
Failure to write the last item in the list was caused by a bug in the display function that caused it to terminate before displaying the last node.
If this is a homework question and you turn in my code, I will find you, drive to your house, and shoot a rotten potato through your bedroom window with a cannon.

Okay, I started to put this in the comments, but putting code in comments will get brickbats :). This is not tested, and there are myriad ways to approach it (given I've diagnosed the problem correctly :) ), but one way that might work to fix your create method is offered as follows: (Note that I've simplified your loop, just using the normal termination condition for the 'for' loop construct, and eliminated the 'if..break' within the loop as its no longer needed. The "->next" member will always be initialized to a new member if there's one left to create, otherwise its NULL, so we don't need the ending assignment:
void create(struct node **h,int num)
{
int i;
struct node *temp=*h;
for(i=0;i<num;i++)
{
temp->data=i;
if (i==(num-1))
temp->next=NULL;
else
temp->next=malloc(sizeof(struct node));
temp=temp->next;
}
}

Related

Why is this code stuck in an infinite loop?

Why is head is going to some random value?
// Simple insertion at the starting of link list
#include<iostream>
using namespace std;
struct node{
int d;
node *next;
}; // creation of node
node *head=new node; // is there any problem?
void insert(int x)
{
if (head==NULL) { // is there something wrong?
head->d=x;
haad->next=NULL;
} else {
node *t=new node;
t->d=x;
t->next=head;
head=t;
}
}
int main() {
insert(1); // function calling
insert(2); // function calling
insert(3); // function calling
while(head!=NULL) {
cout<<head->d<<" ";
head=head->next;
} // this is going on to infinity
return 0;
}
This code is lopping till infinity and I am not able to understand why?
Why is head going to some random value after 3 2 1? Is there any problem in declaring head globally?
head is going to some random value because the last element in your list is pointing with next to a random value.
This last element is the first node you created in this line:
node *head=new node;
By doing that, you are allocating memory for this node on the heap, however, you're not setting any values to the node's fields, including next. Then in the loop, when head is pointing to the last node (that was allocated first) head->next is not NULL and therefore the loop continues.
Three side notes:
Using head itself to iterate over the list elements is not a good idea since you're losing the pointer to the head of the list.
head can be declared globally but usually you should have a good reason for that. In your program I'd define it in main() and pass it to the functions that need it.
This code:
if (head==NULL) { // is there something wrong?
head->d=x;
haad->next=NULL;
doesn't make lots of sense: it will never run, and in case it will --> segmentation fault (because if head is NULL you cannot refer to its fields.
Hope it helps.

Need help coding iterator for a circular linked list in C++

So I'm creating a circular linked list to solve the Josephus Problem for an assignment. I had a really bad professor for my C++ class and I don't really know how to do anything in C++. I'm trying to code an iterator to transverse the list, but I have no clue where to start or how to implement it. Can anyone give me an suggestions or advice on how to start coding this?
It's pretty much just like the std::list iterator, except the end iterator is where the next pointer is the head of the list, not when it's NULL. A reference page will tell you what you're supposed to implement. The underlying representation will be a pointer to a list node, operator* will return a reference to the data, operator++ will set the pointer to next, etc.
Alternatively, use an array implementation with modular arithmetic.
Josephus problem is if N people have decided to elect a leader by arranging
themselves in a circle and eliminating every Mth person around the circle, closing ranks as each person drops out. Find which person will be the last one remaining.
Here is a very simple implementation of this problem in C++.
#include<iostream>
#include<stdio.h>
#include<cstdlib>
#include<stdlib.h>
using namespace std;
struct node
{ int info;
struct node *next;
}arr[]={{rand(),arr+1},{rand(),arr+2},{rand(),arr+3},{rand(),arr+4},{30,arr}};
typedef struct node* Node;
void josephus(Node);
int main()
{
josephus(arr);
system("pause");
}
void josephus(Node head)
{
Node ptr,temp;
int length=1,position,i;
ptr=head;
while(ptr->next!=head)
{
ptr=ptr->next;
length++;
}
ptr=head;
printf(" Enter the position at which element should get eliminated ");
scanf("%d",&position);
while(length>1)
{
i=1;
while(i<position)
{
ptr=ptr->next;
i++;
}
temp=ptr;
ptr=ptr->next;
free(temp);
length--;
}
printf("\n Last Element Left is %d Its address is %u \n",ptr->info,ptr);
}
For more details visit-
https://github.com/SahdevKansal02/Data-Structures-And-Algorithms.git

What has gone wrong with this sorting code using Linked Lists?

I want to say that I just started learning C++ and I'm having a fairly good grip on just insertion, deletion, reversing, finding the element and element in a position. I've tried to sort using Bubble Sort(?) and the program is crashing. Please help me.
struct node
{
int data;
struct node* link;
};
typedef struct node* NODE;
NODE rearr(NODE root)
{
NODE temp=root;
while(temp!=NULL)
{
NODE curr=temp;
while(curr!=NULL)
{
if(curr->data>(curr->link)->data)
{
int temp1=curr->data;
curr->data=(curr->link)->data;
(curr->link)->data=temp1;
}
curr=curr->link;
}
temp=temp->link;
}return root;
}
There are insert and delete functions too, but I haven't copied here. If you want, I'll post the whole program.
You never test to see if curr->link is null or not. Which causes a fault when you check its data memeber.
if(curr->link != NULL && curr->data>(curr->link)->data)

Geting Data from a Tree Structure

I have a tree structure that i am creating the following way. The tree is created correctly as far as i know. But when i want to get the data from a node, i get some weird acsii symbols.
How I set the data.Lets say its empty. Doesn't matter at the moment. I have a value in my program. The function feeds itself until i get to the end of the data.
struct Node {
char Data;
Node* Left;
Node* Right;
};
Node maketree(0,s,split)
{
Node node;
node.Data=' ';
Node n1=subsplit(0,s,splitingat);
Node n2= subsplit(1,splitingat+1,e);
node.Left=&n1;
node.Right=&n2;
return node;
}
This is how i get data from the tree.
char decode(Node node,string text)
{
int currentindex=0;
Node sub=node;
{
}
if(text[currentindex]=='0')
{
sub=*sub.Left;
cout<<" x "<<sub.Data<<endl;
}
else if(text[currentindex]=='1')
{
sub=*sub.Right;
cout<<" x "<<sub.Data<<endl;
}
// cout<<sub.Data<<endl;
}
I think that the mistake is that I am printing out the pointer and not the node. But I don't know where I went wrong.
The source of your problem appears to be here:
Node node;
node.Data=' ';
Node n1=subsplit(0,s,splitingat);
Node n2= subsplit(1,splitingat+1,e);
node.Left=&n1; // danger Will Robinson!
node.Right=&n2;
return node;
You're taking the addresses of local, temporary, automatic variables and storing them in pointers that you return through node. As soon as that return executes, n1 and n2 are destroyed and node.Left and node.Right are left pointing to garbage. You may be able to fix this like so:
Node* n1=new Node(subsplit(0,s,splitingat));
Node* n2=new Node(subsplit(1,splitingat+1,e));
// side note: probably better to have subsplit() return dynamically-allocated Node*s to avoid the copy
node.Left=n1;
node.Right=n2;
but you may still have issues crop up if similar things are being done elsewhere.
Kind of along the same lines, in your second block of code, you are making a copy of each node you examine and storing it into sub. It would probably make more sense to have sub be a Node*.
And finally, to avoid memory management issues (almost) altogether, use shared_ptr<Node> instead of Node* in all of the above. :)

Basic C++ programming question

I am in process of learning c++. I am working on creating a linkedlist data structure. One of the functions that displays the values of nodes in the structure does not work. For some reason the while loop that traverses through nodes doesn't work in the display function, hence I can't see the values in those nodes. Does anyone see what the problem is? I've been staring at the code for a while and not sure what is wrong here.
Thanks for your help in advance.
Header:
// linklist.h
// class definitions
#ifndef LINKLIST_H
#define LINKLIST_H
class linklist
{
private:
// structure containing a data part and link part
struct node
{
int data;
node *link;
}*p;
public:
linklist();
void append(int num);
void addatbeg(int num);
void addafter(int loc, int num);
void display();
int count();
void del(int num);
~linklist();
};
#endif
.cpp file
// LinkedListLecture.cpp
// Class LinkedList implementation
#include"linklist.h"
#include<iostream>
using namespace std;
// initializes data member
linklist::linklist()
{
p =NULL;
}
// adds a node at the end of a linked list
void linklist::append(int num)
{
node *temp, *r;
// if the list is empty, create first node
if(p==NULL)
{
temp = new node;
temp->data = num;
temp->link = NULL;
}
else
{
// go to last node
temp = p;
while(temp->link!=NULL)
temp = temp->link;
// add node at the end
r = new node;
r->data=num;
r->link=NULL;
temp->link=r;
}
}
// displays the contents of the linked list
void linklist::display()
{
node *temp = p;
cout<< endl;
// traverse the entire linked list
while(temp!=NULL) // DEBUG: the loop doesn't work
{
cout<<temp->data<<" ";
temp = temp->link;
}
void main()
{
linklist l;
l.append(14);
l.append(30);
l.append(25);
l.append(42);
l.append(17);
cout<<"Elements in the linked list:";
l.display(); // this function doesn't work
system("PAUSE");
}
You never set p to a non NULL value.
if(p==NULL)
{
p = new node;
p->data = num;
p->link = NULL;
}
I think GWW has highlighted the issue, but part of learning to program it to learn how to identify the mistakes.
If you do something and don't get the expected result you could:
Use the visual c++ debugger to step through and see the values of your variables.
Put in log lines to report information you think is important
inspect the code - if you think something is right but it doesn't work, then go to an earlier step and check it does the right thing.
Add unit tests, or follow design by contract adding pre/post conditions and class invariants.
Learning to program C++ by writing a linked list is like learning math by adding 1 + 1. It is old fashioned thinking, slow and mostly boring without having any context.
Math isn't calculating, like C++ programming isn't pointer manipulation. At some stage you might need to know about it, but your better off learning other important things like stl and boost.
If it was understood that append() ment create something, find the end of the list, add it. you could then see that in you append function you have create something mixed uyp with move to the end of the list, but you never add it.