Copy Linked List to Another List? - c++

I need help in linked list, to make a function for copy a list to another list
I code with Visual Studio 2012. Here is my code and the error that I get:
ERROR:
Unhandled exception at 0x0111544F in linked list.exe: 0xC0000005:
Access violation writing location 0xCDCDCDCD.
Could someone please tell me what's the mistake and how to fix it?
#include <iostream>
using namespace std;
struct node
{
int info;
node *next;
};
void PrintList (node *C)
{
node *P;
cout<<"Node content = (";
P = C;
while(P!=NULL)
{
cout<<P->info;
P = P->next;
if(P != NULL)
cout<<",";
}
cout<<")"<<endl;
}
void copylist (node *Y, node **Z)
{
node *P, *Q;
int temp;
if (Y==NULL)
{
cout<<"the list is empty"<<endl;
*Z=NULL;
}
else
{
P=Y;
Q=*Z;
while (P->next!=NULL)
{
temp=P->info;
Q->info=temp;
P=P->next;
Q=Q->next;
}
}
}
void insertnode (int *A, node **Q)
{
node *N, *P;
N=new node;
N->info=*A;
N->next=NULL;
if(*Q==NULL)
*Q=N;
else
{
P=*Q;
while (P->next!=NULL)
P=P->next;
P->next=N;
}
}
int main ()
{
node *z;
node *duplicate;
z=NULL;
duplicate=new node;
int e;
int i;
int *temp;
temp=new int;
cout<<"the number of element : ";
cin>>e;
cout<<" LIST Z CONTENT : " <<endl;
PrintList (z);
for (i=0;i<e;i++)
{
cin>>*temp;
insertnode(temp, &z);
}
copylist(z,&duplicate);
cout<<" DUPLICATE LIST CONTENT : "<<endl;
PrintList(duplicate);
}

Please note that in main function, you are trying to print an empty list with the following code:
cout<<" LIST Z CONTENT : " <<endl;
PrintList (z);
So, you may want to modify your print function as:
void PrintList(node *C)
{
if (C == NULL) return; // return if the list is empty or print out a message
node *P = C;
cout << "Node content = (";
while (P != NULL)
{
cout << P->info;
P = P->next;
if (P != NULL)
cout << ",";
}
cout << ")" << endl;
}
And in your copy function, you forgot to create new node and keep the link to it during the copy process. Here is the code that would work:
void copylist(node *Y, node **Z)
{
if (Y == NULL)
{
cout << "the list is empty" << endl;
*Z = NULL;
}
else
{
node*P = Y;
node *Q = NULL;
while (P != NULL)
{
node* newNode = new node; // first create a node (allocate memory)
newNode->info = P->info; // then fill the info
newNode->next = NULL;
if (Q == NULL)
{
Q = newNode;
*Z = Q;
}
else
{
Q->next = newNode;
Q = Q->next;
}
P = P->next;
}
}
}
Lastly, your main function does not return anything!! You may want to add
return 0;
at the end.
Try replacing your main function with:
int main()
{
node *z = NULL;
node *duplicate = NULL;
int e;
cout << "The number of elements : ";
cin >> e;
cout << "enter elements with a space between them : ";
while (e--)
{
int temp;
cin >> temp;
insertnode(temp, &z);
}
cout << " LIST Z CONTENT : " << endl;
PrintList(z);
copylist(z, &duplicate);
cout << " DUPLICATE LIST CONTENT : " << endl;
PrintList(duplicate);
cin >> e;
return 0;
}
Alternatively, for copying a list to another, you can call the insertnode function in a loop for adding all the data of the original list to the new list in a loop. This will make your copy function even shorter.
For more information about Linked Lists:
http://en.wikipedia.org/wiki/Linked_list
Happy coding!

You can't copy a list without allocating memory.
You have an access violation cause you're not creating new nodes in your destination list when you copy, but rely on whatever (corrupt pointer) is in next when you use a node.
Other than that you have a small memory leak.
Note the lines with comments:
void copylist (node *Y, node **Z)
{
node *P, *Q;
if (Y==NULL)
{
cout<<"the list is empty"<<endl;
//*Z=NULL; // memory leak! lost pointer of caller!
}
else
{
P=Y;
Q=*Z;
while (P->next!=NULL)
{
Q->info = P->info;
P=P->next;
Q->next = new node(); // missing allocation!
Q = Q->next;
}
Q->next = null; // close new list.
}
}

Related

Only Printing the First Value of Linked List

I have no idea why display function is not displaying anything other than the first node's data. I've tried switching the While(p!=NULL) to while(p->next!= NULL but when I do that instead of only the first node's data displaying no data is being displayed.
#include <iostream>
using namespace std;
class Node {
public:
int no;
Node* next;
};
Node* createNode(int no1) {
Node* n = new Node();
n->no = no1;
n->next = NULL;
return n;
}
void addValue(int x, Node** head) {
//insert first node into linked list
Node* n = createNode(x),*p = *head;
if (*head == NULL) {
*head = n;
}
//insert second node onwards into linked list
else {
while (p->next!= NULL) {
p->next = n;
p = p->next;
}
}
}
void display(Node *head) {
Node* temp = head;
// temp is equal to head
while (temp->next!=NULL) {
cout << temp->no;
temp = temp->next;
}
}
int main() {
int num; char choice;
Node* head = NULL;
do {
cout << "Enter a number : ";
cin >> num;
addValue(num,&head);
cout << "Enter [Y] to add another number : ";
cin >> choice;
} while (choice == 'Y');
cout << "List of existing record : ";
display(head);
return 0;
}
I've tried changing the contents fo the else while loop in the addRecord function to p = p->next; p->next = n; in that order to no avail.
In the while loop, it should be
while (p->next!= NULL) {
p = p->next;
}
p->next = n;
Traverse until the end of linked list is reached and then, add the new entry.

How to remove a certain node from a linked list by the data its holding?

We are suppose to enter a string, and then find where the string is in the linked list and remove that node
when i insert to the front of the list, so i enter data values a, b, c , d, when i print it it comes up as d,c,b,a. Now i insert to the rear of it, entering f and g, and the list now looks, d,c,b,a,f,g. I want to remove f but it just use the remove function it does not and still output the same list
using namespace std;
struct node {
string data;
node* next;
};
node* addFront(node* s);
node* addRear(node* s);
void remove(node* head, string abc);
void print(node* head);
int main() {
node* head = NULL;
cout << "Enter 5 data strings\n";
cout << "This will be inserted from the back\n";
for (int i = 0; i < 5; i++) {
head = addFront(head);
}
print(head);
cout << "Enter 3 strings and this will be inserted from the back of the orignal string\n";
for (int i = 0; i < 3; i++) {
head = addRear(head);
}
print(head);
cout << "Removing the head node\n";
string n;
cout << "Enter a string to remove\n";
cin >> n;
remove(head, n);
print(head);
}
node* addFront(node* s)
{
node* person = new node;
cin >> person->data;
person->next = s;
s = person;
return s;
}
node *addRear(node*s ) {
node* person = new node;
cin >> person->data;
person->next = NULL;
if (s == NULL) {
return person;
}
else {
node* last = s;
while (last->next != NULL) {
last = last->next;
}
last->next = person;
}
return s;
}
void remove(node* head, string a) {
node* previous = NULL;
node* current = head;
if (current == NULL) {
cout << "Value cannot be found\n";
return;
}
else {
while (previous != NULL) {
if (current->data == a) {
previous->next = current->next;
delete current;
break;
}
current = current->next;
}
}
}
void print(node * head)
{
node* temp = head;
while (temp != NULL) // don't access ->next
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
In remove function, previous is most certainly NULL when you hit that while loop.
Perhaps consider a do-while loop instead (with better handling of previous).
You may be better off handling the first node in a different manner since the holder of its previous is essentially the root pointer.

Linked List Program error in C++

I tried implementing Linked List using C++ using a structure.
I've included three functions - Size, Insertion and Deletion from the end.
The program compiled successfully. During execution, when I tried to give input for the LLInsert() function, there was just a cursor blinking on my execution window. I don't know if the function returned to main.
Also the LLSize() doesn't return 0 when I try to find the Size of a empty list.
I can't seem to figure out what I'm doing wrong. Here is my code.
#include<iostream>
using namespace std;
struct LL {
LL *next = NULL;
int data;
};
int LLSize(LL *head) {
LL *current = new LL;
current = head;
int count = 0;
while(current != NULL) {
current = current -> next;
count ++;
}
return count;
}
void LLInsert(LL *head,int value) {
LL *current = new LL;
current = head;
LL *Newnode = new LL;
Newnode -> data = value;
Newnode -> next = NULL;
if(head == NULL) {
head = Newnode;
return;
}
while(current->next != NULL) {
current = current->next;
}
current->next = Newnode;
return;
}
int LLDelete(LL *head) {
LL *current = new LL;
current = head;
int deleteddata;
while(current->next->next != NULL) {
current = current->next;
}
current->next->data = deleteddata;
current->next = NULL;
return deleteddata;
}
int main() {
int choice;
LL *A;
while(1) {
cout << "1. Size\n2. Insert\n3. Delete\n4. Exit" << endl;
cout << "Enter a choice : ";
cin >> choice;
switch(choice) {
case 1 : {
cout << "\nLength = " << LLSize(A) << endl;
break;
}
case 2 : {
int value;
cout << "\nEnter the element to insert : ";
cin >> value;
LLInsert(A,value);
break;
}
case 3 : {
cout << LLDelete(A);
break;
}
case 4 : {
exit(0);
}
default : {
cout << "\nInvalid choice. Enter a valid choice " << endl;
break;
}
}
}
}
Don't use using namespace.
Create a type for the list and a type for the nodes
struct LL {
LL* next;
int data;
};
struct L {
LL* head;
};
Use references and don't allocate new memory in each function
int LLSize(L& list) {
LL *current = list.head;
Check if the head of the list is set and use nullptr
if (list.head == nullptr) {
Use an instance of the list and not a pointer
int main() {
int choice;
L A;
Use a debugger like gdb to analyze your program.
Clean up at the end. Delete memory you allocated with new. One delete for each new.

Deletion of specific node from singly Linked list with the help of data given

I am trying to delete the node of specific data. For this, I am using deleteNode function but not able to delete. Please see the code:
#include<iostream>
using namespace std;
class node
{
public:
int data;
node* next;
///constructor for initializing the data-
node(int d)
{
data=d;
next=NULL;
}
};
void addAtEnd(node* &head,int data)
{
if(head==NULL)
{
head=new node(data);
return ;
}
node* temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
node* n =new node(data);
n->data=data;
temp->next=n;
n->next=NULL;
return;
}
AddAtTail(node* head,int d)
{
node* ptr=head;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
node *n=new node(d);
ptr->next=n;
n->next=NULL;
}
AddAtPosition(node* head,int p,int d)
{
///2 3 4 6 7 8 -1
///4th Position-
node*ptr=head;
int jump=1;
while(jump<=p-1)
{
jump++;
ptr=ptr->next;
}
node*n=new node(d);
n->next=ptr->next;
ptr->next=n;
}
/// Delete First node
void deleteFirst(node *&head)
{
head=head->next;
}
///Delete last node;
void deleteLast(node* head)
{
node* ptr=head;
while(ptr->next->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=NULL;
}
**///Delete Specific Node :-**
Here the function starts for deleting the node. I am trying to delete the node that has data 3 I am taking data as input from main function.
void deleteData(node* head,int d)
{
node*ptr=head;
while(ptr->next!=NULL)
{
if(ptr->next->data==d)
{
ptr=ptr->next->next;
return;
}
ptr=ptr->next;
}
}
void takeInput(node*& head)
{
int d;
cin>>d;
while(d!=-1)
{
addAtEnd(head,d);
cin>>d;
}
}
void print(node* head)
{
while(head!=NULL)
{
cout<<head->data<<"=>";
head=head->next;
}
}
AddAtFront(node* &head,int d)
{
///create new node;
node*n=new node(d);
n->next=head;
head=n;
}
int main()
{
node* head(NULL);
takeInput(head);
print(head);
cout<<endl<<endl<<endl<<"---------- Here The Insertion Process starts at different Positions -----------"<<endl;
cout<<endl<<"Adding at Tail"<<endl;
AddAtTail(head,9);
print(head);
cout<<endl<<"Adding at Position p"<<endl;
int p,d;
cout<<"Enter Position and data :"<<endl;
cin>>p>>d;
AddAtPosition(head,p,d);
print(head);
cout<<endl<<"Adding at Front"<<endl;
cout<<"Enter data to add at front : "<<endl;
cin>>d;
AddAtFront(head,d);
print(head);
cout<<endl<<endl<<endl;
cout<<endl<<"-------------------- NOW LETS PERFORM DELETION ------------------"<<endl;
cout<<endl<<"Deleting first node :"<<endl;
deleteFirst(head);
print(head);
cout<<endl;
cout<<endl<<"Deleting Last node :"<<endl;
deleteLast(head);
print(head);
cout<<endl;
cout<<"deleting specific node"<<endl;
cout<<"Enter data to delete"<<endl;
cin>>d;
deleteData(head,d);
print(head);
cout<<endl;
return 0;
}
Please see DeleteNode function in which I am trying to delete the node.
Why node is not deleting? Here is the function:
**///Delete Specific Node i.e- data :-**
void deleteData(node* head,int d)
{
node*ptr=head;
while(ptr->next!=NULL)
{
if(ptr->next->data==d)
{
ptr=ptr->next->next;
return;
}
ptr=ptr->next;
}
}
But Node is not deleting.
Your delete... functions are not actually deleting anything. You are just manipulating pointers but are leaking the actual node objects. And you are not taking into account the possibility that the node being deleted is the head node, which requires updating the head to point at the next node.
Also, your functions will crash on an empty list, and deleteLast will crash on a list with fewer than 2 nodes.
And deleteData is not enumerating nodes correctly.
Try something more like this instead:
#include <iostream>
using namespace std;
class node {
public:
int data;
node* next;
///constructor for initializing the data-
node(int d) {
data=d;
next=NULL;
}
};
node* findLast(node *head, node **before) {
if (before) *before = NULL;
node *last = head;
if (last) {
while (last->next) {
if (before) *before = last;
last = last->next;
}
}
return last;
}
node* addAtFront(node* &head, int data) {
node* n = new node(data);
n->next = head;
head = n;
return n;
}
node* addAtEnd(node* &head, int data) {
node *last = findLast(head, NULL);
node* n = new node(data);
if (last) {
last->next = n;
} else {
head = n;
}
return n;
}
node* addAtPosition(node* &head, int p, int d) {
if ((!head) || (p <= 0)) {
return addAtFront(head, d);
}
node *ptr = head;
node *temp;
do {
temp = ptr;
ptr = ptr->next;
}
while ((ptr) && (--p > 0));
node *n = new node(d);
n->next = temp->next;
temp->next = n;
return n;
}
/// Delete First node
void deleteFirst(node* &head) {
if (head) {
node *ptr = head;
head = head->next;
delete ptr;
}
}
///Delete last node
void deleteLast(node* &head) {
node *beforeLast;
node *last = findLast(head, &beforeLast);
if (last) {
if (beforeLast) {
beforeLast->next = NULL;
}
if (head == last) {
head = NULL;
}
delete last;
}
}
///Delete Specific Node
void deleteData(node* &head, int d) {
node *before = NULL;
node *ptr = head;
while (ptr) {
if (ptr->data == d) {
if (before) {
before->next = ptr->next;
}
if (head == ptr) {
head = head->next;
}
delete ptr;
return;
}
before = ptr;
ptr = ptr->next;
}
}
void takeInput(node* &head) {
int d;
if (!((cin >> d) && (d != -1))) return;
node *last = findLast(head, NULL);
node *n = new node(d);
if (last) {
last->next = n;
} else {
head = n;
}
last = n;
while ((cin >> d) && (d != -1)) {
n = new node(d);
last->next = n;
last = n;
}
}
void print(node* head) {
while (head) {
cout << head->data << "=>";
head = head->next;
}
}
int main() {
node* head = NULL;
takeInput(head);
print(head);
cout << endl;
cout << endl << endl;
cout << "---------- Here The Insertion Process starts at different Positions -----------" << endl << endl;
cout << "Adding at End" << endl;
addToEnd(head, 9);
print(head);
cout << endl;
cout << "Adding at Position p" << endl;
int p, d;
cout << "Enter Position and data :" << endl;
if (cin >> p >> d) {
addAtPosition(head, p, d);
print(head);
cout << endl;
}
cout << "Adding at Front" << endl;
cout << "Enter data to add at front : " << endl;
if (cin >> d) {
addAtFront(head, d);
print(head);
cout << endl;
}
cout << endl << endl << endl;
cout << "-------------------- NOW LETS PERFORM DELETION ------------------" << endl << endl;
cout << "Deleting first node :" << endl;
deleteFirst(head);
print(head);
cout << endl;
cout << endl << "Deleting Last node :" << endl;
deleteLast(head);
print(head);
cout << endl;
cout << "deleting specific node" << endl;
cout << "Enter data to delete" << endl;
if (cin >> d) {
deleteData(head, d);
print(head);
cout << endl;
}
cout << "deleting remaining nodes" << endl;
node *ptr = head;
while (ptr) {
node *temp = ptr;
ptr = ptr->next;
delete temp;
}
return 0;
}
That being said, you really should be using std::list (double linked) or std::forward_list (single linked) instead. Let the STL do the hard work for you.
In your delete node function, you are changing the value of the local variable, ptr. But you are not changing the "next" pointer of the node pointing to the one you want to delete. So it stays in the list. The value of your local pointer becomes irrelevant as soon as you leave the function.
This line is the problem: ptr=ptr->next->next;
You need to change its "next" value. Something like (I haven't compiled and tested this; it is a suggestion to point you in the right direction.)
void deleteData(node* head,int d)
{
node*ptr=head;
while(ptr->next!=NULL)
{
if(ptr->next->data==d)
{ /* pointer->next points to the node you want to delete.
point it instead to the one beyond */
ptr->next=ptr->next->next;
return;
}
ptr=ptr->next;
}
}
You will then have a memory leak, as you are not freeing the memory to the node you are deleting.
You'd need something like:
void deleteData(node* head,int d)
{
node*ptr=head;
while(ptr->next!=NULL)
{
if(ptr->next->data==d)
{ /* pointer->next points to the node you want to delete.
point it instead to the one beyond,
freeing the memory of the deleted node */
node * pNodeToDelete = ptr->next;
ptr->next=ptr->next->next;
free(pNodeToDelete)
return;
}
ptr=ptr->next;
}
}

Segmentation fault (core dumped) ? what is it and why is caused ??? ( doubly circular linked list program in c++) [duplicate]

This question already has answers here:
What is a segmentation fault?
(17 answers)
Closed 7 years ago.
My program (its not complete but I would really like to know my error):
#include <iostream.h>
using namespace std;
class dcllnode
{
private:
int data;
dcllnode *next;
dcllnode *prev;
public:
dcllnode(int ele)
{
data = ele;
prev = next;
next = prev;
}
friend class dcll;
};
class dcll
{
private:
dcllnode *head;
public:
dcll()
{
head = NULL;
}
void create();
void inserts(int ele);
void inserte(int ele);
void inserta(int ele, int pos);
void insertb(int ele, int pos);
void dels();
void dele();
void dela();
void display();
};
void dcll::create()
{
if (head == NULL)
{
head = new dcllnode(0);
cout << "list is created";
}
else
{
cout << "list has already been created";
}
}
void dcll::inserts(int ele)
{
if (head == NULL)
cout << "please create the list first ";
else
{
dcllnode *x;
x = new dcllnode(ele);
x->prev = head;
x->next = head->next;
(head->next)->prev = x;
head->next = x;
cout << "list is modified";
}
}
void dcll::inserte(int ele)
{
if (head == NULL)
cout << "please create the list first ";
else
{
dcllnode *x;
x = new dcllnode(ele);
x->next = head;
x->prev = head->prev;
(head->prev)->next = x;
head->prev = x;
cout << "list is modified";
}
}
void dcll::dels()
{
if (head == NULL)
cout << "please create the list first ";
else
{
dcllnode *x;
head->next = x;
head->next = x->next;
(x->next)->prev = head;
x->next = NULL;
x->prev = NULL;
delete(x);
cout << "list is modified";
}
}
void dcll::dele()
{
if (head == NULL)
cout << "please create the list first ";
else
{
dcllnode *x;
head->prev = x;
head->prev = x->prev;
(x->prev)->next = head;
x->prev = NULL;
x->next = NULL;
delete(x);
cout << "list is modified";
}
}
void dcll::display()
{
if (head == NULL)
cout << "please create the list first ";
else
{
dcllnode *p = head->next;
while (p != head)
{
cout << "\n" << p->data;
p = p->next;
}
}
}
int main()
{
dcll l1;
l1.create();
l1.inserte(10);
l1.display();
l1.inserts(20);
return 0;
}
The segmentation problem is not occurring when I use only the create function. I would like to know how to solve such problems and how to avoid segmentation errors in future any information and/or help is appreciated.
You typically get segmentation faults when using illegal pointers (null or uninitialized pointers, or pointers pointing to unallocated or otherwise illegal memory).
In your case it's easy to see what one of the problems are, it's in the dcllnode constructor where you do
prev = next;
next = prev;
When you do these assignments the pointers next and prev are uninitialized, and their values are indeterminate. Assigning them to each other like this will not initialize them, just make them both have the same indeterminate value. Later when you dereference these pointers you will have undefined behavior leading to your segmentation fault and the crash.
What you probably should to is to initialize both pointers to null:
prev = nullptr; // or 0
next = nullptr; // or 0
[Note: In C++ don't use NULL, use either nullptr (preferred) or if you don't have it then plain 0.]
To complete joachim's answer, in these two statements:
(head->next)->prev = x;
(head->prev)->next = x;
head->next and head->prev can be nullptr so you have to check it before dereferencing the pointer.