I'm trying to copy 1 list to another, but it copies only the first element. When I debug it, it showed me the error on the highlighted line.
Can you help me to solve this error and explain to me what's going wrong?
struct List1 {
int data;
List* next;
};
struct List3 {
int data3;
List3* next3;
};
void copyList(){
if(p==NULL) cout<<"Lista este vida\n";
else
{
c=p;
List3* x = new List3;
while(c!=NULL)
{
***x->data3 = c->data;***
cout<<x->data3<<" ";
c=c->next;
x=x->next3;
}
}
cout <<"\nList has been copied successful\n";
}
You are allocating only 1 List3 node for your x list.
On the first loop iteration, x points to a valid List3 instance. But you are not initializing its next3 member. So on the next loop iteration, the value of x becomes indeterminate, it is not pointing at valid memory.
You need to allocate a separate node for every value that you want to copy. For example:
void copyList()
{
if (p == NULL)
cout << "Lista este vida\n";
else
{
List1 *c = p;
List3* x = NULL;
List3** px = &x;
do
{
*px = new List3;
(*px)->data3 = c->data;
(*px)->next3 = NULL;
cout << (*px)->data3 << " ";
px = &((*px)->next3);
c = c->next;
}
while (c != NULL);
// use x as needed. don't forget to delete all
// of the nodes when you are done using them!
cout << "\nList has been copied successful\n";
}
}
Related
I'm working on a class project and this piece of code won't let me delete an instance of a class without throwing a breakpoint error.
The class is Node, I'm trying to build a singly linked list for data structures and algorithms. I'll include the whole program, it isn't long, but the code in question that's causing the problem is in deleteMin(), the delete u.
#include <iostream>
using namespace std;
// we create a Node class.
class Node { // inside this class we hold two pieces of information.
int x; // the integer x, which is our data.
Node* next; // and the address of the next node.
public:
Node(int x0) : x(x0), next(NULL) { } // Here I've set up a constructor that sets x equal to the argument
// and defaults the next address to NULL.
bool add(int newValue); // Here follows our three required functions.
int deleteMin();
int size();
void printSSL(); // I also added a printSSL() function so that we can test and see what's going on.
};
//Originally I wanted to put these inside of the Node class, but then you'd end up with a unique head and tail for every Node.
//So instead I've left them outside. If you wanted to create multiple SSList's then you'd want to create an object out of these as well.
Node* head; // The first value in the our SLList.
Node* tail; // The last value in our SLList.
int n; // The number of elements in the list.
// I should mention here that head and tail are set equal to the first value in the SLList in the Main() function below.
// Here follows the actual implementation.
// I chose to try and simplify things by focusing on the add() function.
// If the add function organizes the information, and puts it into the SLList in order,
//then deleteMin() only has to pull the first value.
bool Node::add(int newValue) { // add() is a member function of Node and it takes in the newValue were adding to the list.
Node* u = new Node(newValue); // First thing we do is create a new Node using the argument value x. We pass this into a pointer, u.
if (newValue <= head->x) { // Next, we check to see if the new value is less than the head.
u->next = head; // if it is, then our job is done and we just make this new, smaller value, the new head.
head = u; // we do this by making the initial head equal to the next address in the new Node u.
n++; // Once we have the address saved, we make u into the new head and increment n.
return true; // There's no iteration in this case, so this if statement would be O(1).
}//O(1)
else { // If the new value is greater than the head, then we have to store it further back in the SLList.
Node* y = head; // This was the hardest part of the whole thing... I solved it by creating two Node pointers,
Node* z = head; // Both Node pointers are set equal to head, but this is mostly just to ensure that they aren't empty.
while ((newValue > y->x) && (y != tail)) { // Then I set a while loop that looks at whether the new value is less than the value in the head.
z = y; // The while loop continues, moving through the list of values, setting y equal to the next value,
y = y->next; // and using z to keep track of the former value.
} // The loop exits when we either a) hit the end of the SLList, y == tail, or when the new value is
if (y == tail) { // smaller than the next value, newValue < y->x. When the loop exits we have to deal with these two
y->next = u; // scenarios separately. If we reached the end of our list, then adding the new value is as simple as
tail = u; // setting y->next equal to u, then we make u into the new tail.
} // if we didn't reach the end of the list, then we have to set u inbetween z and y. This was really
else { // the only reason I needed z. I needed to be able to update the address of the previous Node, and
z->next = u; // I also needed to have the address of the next Node, this way I could slip u inbetween the two.
u->next = y; // Worst case scenario, this function runs through the entire SLList and then adds the value at the end.
} // I could have shaved off some time by asking if(newValue > tail->x) then run the z->next=u; and u->next=y; after
n++; // after that, but that throws an error becauset ail is a NULL pointer, which is bull#*#!
return true; // because I'm not dealing the tail->next, all I care about is tail->x which isn't NULL.
}//O(n) // But because this is an SSList and not a DLList I have no way of going to the n-2 element.
}//O(max(1, n)) // When that's done, we just increment n and leave the function.
// Considering that the worst case scenario, when x > tail->x, takes us through the whole SLList.
// I'm going to say that this add function is O(n).
int Node::deleteMin() { // The deleteMin() function starts by checking whether or not the
int x = head->x;
Node* u = head;
head = head->next;
delete u; // I have to figure out what the hells going on right here, why can't I delete this?
return x;
}
int Node::size() {
cout << n + 1 << endl;
return n + 1;
}
void Node::printSSL() {
Node* u = head;
cout << "Head:";
for (int i = 0; i <= n; i++) {
cout << i << ":(" << u->x << ", " << u->next << ") ";
u = u->next;
}
cout << " Tail" << endl;
}
int main()
{
Node one(1);
head = &one;
tail = &one;
one.printSSL();
one.deleteMin();
}
You declared an object of the type Node
Node one(1);
You may not apply the operator delete to a pointer to the object because the object was not allocated dynamically. It has automatic storage duration.
Pay attention to that it is a bad idea when functions depend on global variables. For example you will be unable to define two lists in your program.
What you need is to define a class named something like List the following way
class List
{
private:
Node *head = nullptr, *tail = nullptr;
public:
// special member functions and some other member functions;
void clear();
~List() { clear(); }
};
and to allocate nodes dynamically that will be inserted in the list.
The destructor and the function clear will delete all the allocated nodes in the list.
class Node also should be defined as a nested class of the class List.
For example the function clear can be defined the following way
#include <functional>
//...
void List::clear()
{
while ( head )
{
delete std::exchange( head, head->next );
}
tail = nullptr;
}
#include <iostream>
using namespace std;
class SLList { // SLList is the object that holds the entire list.
public: // The Node class lives inside the SLList class.
struct Node {
int data;
Node* next;
Node(int x0) : data(x0), next(NULL) {}
Node() : data(NULL), next(NULL) {}
};
Node* head;
Node* tail;
int n;
SLList() : n(0) {
Node* initial = new Node();
head = initial;
tail = initial;
cout << "You've created a new SSList" << endl;
}
bool add(int newValue);
int deleteMin();
int size();
void printSSL();
};
bool SLList::add(int newValue) { //
if (n == 0) {
head->data = newValue;
n++;
return true;
}
else {
Node* u = new Node(newValue);
if (newValue <= head->data) { //
u->next = head; //
head = u; //
n++; //
return true; //
}//O(1)
else { //
Node* y = head; //
Node* z = head; //
while ((newValue > y->data) && (y != tail)) { //
z = y; //
y = y->next; //
} //
if (y == tail && newValue > y->data) {
y->next = u; //
tail = u; //
} //
else { //
z->next = u; //
u->next = y; //
} //
n++; //
return true;
}
}//O(n) //
}//O(max(1, n)) //
int SLList::deleteMin() {
int x = head->data;
Node* u = head;
head = head->next;
delete u;
n--;
return x;
}//O(1)
int SLList::size() {
cout << n + 1 << endl;
return n + 1;
}//O(1)
void SLList::printSSL() {
Node* u = head;
cout << n << " Nodes|" << "Head:";
for (int i = 0; i < n; i++) {
cout << i << ":(" << u->data << ", " << u->next << ") ";
u = u->next;
}
cout << " Tail" << endl;
}//O(n)
int main() {
SLList* one = new SLList;
one->printSSL();
one->add(30);
one->printSSL();
one->add(20);
one->printSSL();
for (int i = 0; i < 7; i++) {
int x = rand() % 50;
one->add(x);
one->printSSL();
}
for (int i = 0; i < 9; i++) {
one->deleteMin();
one->printSSL();
}
}
I am new to linked lists.My exercises are something like:"write a function which puts the value x to the end of your linked list".So , my code will look like this:(p is a pointer to the first value)
struct node
{
int info;
node *next;
};
void LastElement(int x , node * & p)
{
node *q = new node;
q = p;
while (q -> next != NULL)
q = q -> next;
q->next->info = x;
q->next->next = NULL;
}
My question is:How do i verify this program?What do i write in the main function?Will i create an array or...?
To simply test your code you can do a function like:
void check(node *p) {
while (p != nullptr) {
std::cout << p->info << std::endl;
}
}
But this function doesn't gonna work with your actual code, because when you do:
q->next->info = x;
q->next->next = NULL;
Your programme gonna crash, because q->next at this moment is null. If you wan't to add a new node whit the value x create a new one and put it in like:
// generate the need node
node *new_node = new node;
new_node->info = x;
// push the new node to the linked list
node->next = new_node;
But if you wan't to modify the last node do:
node->info = x;
// but not like you did:
// node->next->info = x;
You should write a test function that validates that the linked list is of the correct shape. That test function could, for example, walk your linked list in parallel with a std::vector and test that elements are the same pairwise and that the length is the same. Its prototype would be something like bool testEqual(node * list, std::vector<int>)
Now simply call LastElement a few times and then check that the resulting linked list is of the correct shape.
Here is a reference implementation, you can adapt it to arrays if you want:
bool testEqual(node * list, const std::vector<int>& test) {
for (int i = 0; i < test.size() && list != nullptr; i++)
if (test[i] != list->info) {
std::cerr << "mismatch at index " << i << std::endl;
return false;
}
list = list->next;
}
if (i == test.size() && list == nullptr) {
return true;
} else {
std::cerr << "list is too " << (list == nullptr ? "short" : "long" ) << std::endl;
return false;
}
}
Simply call this as testEqual(theList, {1,2,3,4,5}).
For my homework, I need to make methods that add (append) and remove (serve) nodes from a Deque. However, when trying to serve the last node I struggle with memory leaks since I don't know how to retrieve the node that's not being used anymore to the system.
Here's the code for the method.
void Deque::serveAtRear(int &x)
{
if(empty())
{
cout << "Fila Vazia" << endl;
exit(0);
}
else
{
DequePointer q; //Pointer before p
q = head; //q starts at the deque's head
p = head->nextNode; //Pointer for the next node
if(q->nextNode==NULL) //If there's only one node
{
x = q->entry; //x will receive the value of the removed node to print it afterward
head = tail = NULL;
delete p; //I don't know if I'm using the "delete" right
}
else
{
while(p->nextNode != NULL)
{
p = p->nextNode;
q = q->nextNode;
if(p->nextNode==NULL)
{
q->nextNode=NULL;
}
}
x = p->entry;
delete p->nextNode;
}
delete q->nextNode;
}
}
To add nodes I have this method:
void Deque::appendAtFront(int x)
{
if(full())
{
cout << "FULL" << endl;
exit(0);
}
else
{
p = new DequeNode;
p->entry=x;
if(p == NULL)
{
cout << "Can't insert" << endl;
exit(0);
}
else if(empty())
{
head = tail = p;
p->nextNode=NULL;
}
else
{
p->nextNode=head;
head = p;
}
}
}
Also I can't use the "deque" lybrary
Generic answer to how avoid leaks is: avoid manual memory allocation.
For example you can use smart pointers, e.g. std::unique_ptr and instead of calling new DequeNode call std::make_unique<DequeNode>(). Compiler will then point places where your code needs to be adapted, as you will limit yourself so that each of your DequeNode(s) will be owned by just one unique_ptr at the same time. Example pop function (where head and DequeNode.next are uniuque_ptrs) based on your serveAtRear:
if (!head)
{
return;
}
DequeNode* q; //Pointer before p
DequeNode* p; //will be tail eventually
q = head.get(); //q starts at the deque's head
p = q->next.get(); //Pointer for the next node
if(!p) //If there's only one node
{
x = q->entry; //x will receive the value of the removed node to print it afterward
head.reset(); // hear we release DequeNode pointed by head
}
else
{
while(p->next)
{
q = p;
p = q->next.get();
}
x = p->entry;
q->next.reset(); // here we release tail (i.e. p)
}
Of course implementation of push needs to be adopted too :).
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.
}
}
**struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* Merge(ListNode* list1, ListNode* list2){//list1 2; list2 4
ListNode* result = new ListNode(0);
ListNode* travel = result;
while(list1 || list2){
cout << "hereWhile" << endl;
//cout << list1->val << list2->val << endl;
if(!list1){
travel->val = list2->val;
list2 = list2->next;
travel->next = new ListNode(0);
travel = travel->next;
}
else if(!list2){
travel->val = list1->val;
list1 = list1->next;
travel->next = new ListNode(0);
travel = travel->next;
}
else{
if(list1->val <= list2->val){
travel->next = new ListNode(0);
travel->val = list1->val;
list1 = list1->next;
travel = travel->next;
}
else{
travel->next = new ListNode(0);
travel->val = list2->val;
list2 = list2->next;
travel = travel->next;
}
}
}
cout << "travel at the end: " << (travel == result->next->next) << endl;
delete result->next->next;
//delete travel;
cout << travel->val << endl;
cout << result->val << endl;
cout << result->next->val << endl;
cout << "val: " << result->next->next->val << " end" << endl;
return NULL;
}**
in my case, the above delete method never works.
I have updated my whole code in order to provide more details. This is part of implementing a MergeSort by linked list. And my testcase is this recursion and this Merge function is list1 = {2} and list2 = {4} , so the Merge function is designed to return the head of a linked list {2,4} which has a size of two nodes.
In my code above, I declared a new node to travel->next in each of my if statement and I move travel one step further. Hence after the while loop, my linked list becomes {2,4,0} and I have a pointer "travel" pointing to ListNode{0}. However, it cannot be deleted! I have tried both by "delete result->next->next" and "delete travel" but it can still return result->next->next->val, which is 0! (my last cout statement)
WHY?
I declared this new ListNode (which is a struct) in my heap memory. And I want to delete this ListNode out of the while loop. But my delete never works. Maybe the travel was in heap in the brackets, but came out as stack memory after the while loop because I declare the dynamic memory in my loop?
use this in the loop to prevent memory leak
<pointer to struct for list2> tmp1 = list2;
list2 = list2->next;
delete tmp1;
<pointer to struct for travel> tmp2 = travel; travel = travel->next;
delete tmp2;
I have some questions.
Do you want to remove the whole list of travel or a single node?
What is the initialize value for travel?
you are checking the list1, but not using it inside the loop. Give more details about it.
I assume you need to delete the whole list of travel (list1), and travel is iterator of list1.
travel = list1;
while(list1 != NULL)
{
list1 = list1->next;
delete travel;
travel = list1->next;
}