I tried using cout at various stages to figure but in vain. The program crashes after flushing the first two values in the reversed list. It prints a garbage value as the third value and before it can print the last two values, it crashes.
#include <iostream>
using namespace std;
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
if (s.head->next != NULL) {
head->next = new Node(*(s.head->next));
}
else {
head->next = new Node(NULL);
}
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
if (s.head->next != NULL) {
this->head->next = new Node(*(s.head->next));
}
else {
this->head->next = new Node(NULL);
}
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "\n\nNo elements to pop\n\n";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "\n\nNo elements in the stack\n\n";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "\n\nFlushing s:\n";
s.flush();
return 0;
}
I tried using cout at various stages to figure but in vain. The program crashes after flushing the first two values in the reversed list. It prints a garbage value as the third value and before it can print the last two values, it crashes.
#include <iostream>
using namespace std;
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
if (s.head->next != NULL) {
head->next = new Node(*(s.head->next));
}
else {
head->next = new Node(NULL);
}
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
if (s.head->next != NULL) {
this->head->next = new Node(*(s.head->next));
}
else {
this->head->next = new Node(NULL);
}
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "\n\nNo elements to pop\n\n";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "\n\nNo elements in the stack\n\n";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "\n\nFlushing s:\n";
s.flush();
return 0;
}
Please run it and you'll understand for yourself.
The problem is in function:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
Here you are creating the local stack "s2". When the s2 goes out of scope, it calls the destructor and flushes the whole stack. Better you should remove the flush call from destructor or create the global "s2". Best option will be implement the other logic to reverse the stack.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
so I've an assignment to sort single linked list ascending and descending wise here's the code, in my head it should work as getting the maximum and adding it into a new list and delete the max in order to find the new maximum of the old list.
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node * createNode(int x)
{
Node * newnode = new Node;
newnode-> data = x;
newnode-> next = NULL;
return newnode;
}
class List {
Node *head;
public:
List()
{
head=NULL;
}
void Delete(int x)
{
Node* q;
Node* p = head;
while(head->data==x && head!=NULL)
{
q=head;
head=head->next;
delete(q);
}
p=head;
while(p->next!=NULL)
{
if(p->next->data==x)
{
q=p->next;
p->next=p->next->next;
delete(q);
}
else
{
p=p->next;
}
}
}
void InsertAtBeggining(int x)
{
Node* newnode = createNode(x);
if(head==NULL)
{
head=newnode;
}
else
{
newnode->next=head;
head=newnode;
}
}
void InsertLast(int x)
{
Node* newnode = createNode(x);
Node* p=head;
if(head==NULL)
{
head=newnode;
}
else
{
while(p->next!=NULL) // 4 5 6 7
{
p=p->next;
}
p->next=newnode;
newnode->data=x;
newnode->next=NULL;
}
}
int MAX()
{
Node *p=head;
int m=p->data;
if(head==NULL)
{
cout<<"List is empty! ";
}
else
{
while(p!=NULL)
{
if(p->data>m)
{
m=p->data;
p=p->next;
}
else{
p=p->next;
}
}
return m;
}
}
int MIN()
{
Node *p=head;
int m=p->data;
if(head==NULL)
{
cout<<"List is empty! ";
}
else
{
while(p!=NULL)
{
if(p->data<m)
{
m=p->data;
p=p->next;
}
else{
p=p->next;
}
}
return m;
}
}
int size()
{
int count = 0;
Node* current = head;
while (current != NULL)
{
count++;
current = current->next;
}
return count;
}
/* int locate(int x) {
node* p = head;
int c = 0;
while (p != NULL) {
if (p->data != x) {
p = p->next;
c++;
}
else {
return c;
}
}
return -1;
}
*/
List Ascending_sorting(List l)
{
List l2 = List();
int c=l.size();
while (c!=0)
{
int x=l.MAX();
l2.InsertAtBeggining(x);
l.Delete(MAX());
c--;
l2.print();
cout<<endl;
}
l2.print();
}
/*
List Descending_sorting(List l)
{
List l2 = List();
int c=l.size();
while (c!=0)
{
int x=l.MAX();
l2.InsertLast(x);
l.Delete(MAX());
c--;
}
cout<<"tany print"<<endl;
l2.print();
}
*/
void print()
{
Node *p=head;
while(p!=NULL)
{
cout<<p->data<<endl;
p=p->next;
}
}
};
int main()
{
List l;
l.InsertAtBeggining(9);
l.InsertAtBeggining(2);
l.InsertAtBeggining(3);
l.InsertAtBeggining(4);
l.InsertAtBeggining(1);
l.InsertLast(30);
l.InsertLast(20);
l.InsertLast(60);
l.InsertLast(10);
l.InsertLast(90);
int z;
z = l.MAX();
cout<<"max "<<z<<endl;
l.Ascending_sorting(l);
system("PAUSE");
return 0;
}
I'd like any help :) it's printing l2 inside the while loop but it fails outside of it, also it's not printing the 1.
you should check before derefrence pointers!
actually I changed these lines:
while((head != NULL) && head->data == x)
while((p != NULL) && p->next != NULL)
and after changed you have this code:
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* createNode(int x)
{
Node* newnode = new Node;
newnode->data = x;
newnode->next = NULL;
return newnode;
}
class List
{
Node* head;
public:
List()
{
head = NULL;
}
void Delete(int x)
{
Node* q;
Node* p = head;
while((head != NULL) && head->data == x)
{
q = head;
head = head->next;
delete(q);
}
p = head;
while((p != NULL) && p->next != NULL)
{
if(p->next->data == x)
{
q = p->next;
p->next = p->next->next;
delete(q);
}
else
{
p = p->next;
}
}
}
void InsertAtBeggining(int x)
{
Node* newnode = createNode(x);
if(head == NULL)
{
head = newnode;
}
else
{
newnode->next = head;
head = newnode;
}
}
void InsertLast(int x)
{
Node* newnode = createNode(x);
Node* p = head;
if(head == NULL)
{
head = newnode;
}
else
{
while(p->next != NULL) // 4 5 6 7
{
p = p->next;
}
p->next = newnode;
newnode->data = x;
newnode->next = NULL;
}
}
int MAX()
{
Node* p = head;
int m = p->data;
if(head == NULL)
{
cout << "List is empty! ";
}
else
{
while(p != NULL)
{
if(p->data > m)
{
m = p->data;
p = p->next;
}
else
{
p = p->next;
}
}
return m;
}
}
int MIN()
{
Node* p = head;
int m = p->data;
if(head == NULL)
{
cout << "List is empty! ";
}
else
{
while(p != NULL)
{
if(p->data < m)
{
m = p->data;
p = p->next;
}
else
{
p = p->next;
}
}
return m;
}
}
int size()
{
int count = 0;
Node* current = head;
while(current != NULL)
{
count++;
current = current->next;
}
return count;
}
/* int locate(int x) {
node* p = head;
int c = 0;
while (p != NULL) {
if (p->data != x) {
p = p->next;
c++;
}
else {
return c;
}
}
return -1;
}
*/
List Ascending_sorting(List l)
{
List l2 = List();
int c = l.size();
while(c != 0)
{
int x = l.MAX();
l2.InsertAtBeggining(x);
l.Delete(MAX());
c--;
l2.print();
cout << endl;
}
l2.print();
}
/*
List Descending_sorting(List l)
{
List l2 = List();
int c=l.size();
while (c!=0)
{
int x=l.MAX();
l2.InsertLast(x);
l.Delete(MAX());
c--;
}
cout<<"tany print"<<endl;
l2.print();
}
*/
void print()
{
Node* p = head;
while(p != NULL)
{
cout << p->data << endl;
p = p->next;
}
}
};
int main()
{
List l;
l.InsertAtBeggining(9);
l.InsertAtBeggining(2);
l.InsertAtBeggining(3);
l.InsertAtBeggining(4);
l.InsertAtBeggining(1);
l.InsertLast(30);
l.InsertLast(20);
l.InsertLast(60);
l.InsertLast(10);
l.InsertLast(90);
int z;
z = l.MAX();
cout << "max " << z << endl;
l.Ascending_sorting(l);
system("PAUSE");
return 0;
}
#include <iostream>
using namespace std;
template <typename Object>
struct Node
{
Object data;
Node* next;
Node(const Object &d = Object(), Node *n = (Object)NULL) : data(d), next(n) {}
};
template <typename Object>
class singleList
{
public:
singleList() { init(); }
~singleList() { eraseList(head); }
singleList(const singleList &rhs)
{
eraseList(head);
init();
*this = rhs;
print();
contains(head);
}
void init()
{
theSize = 0;
head = new Node<Object>;
head->next = (Object)NULL;
}
void eraseList(Node<Object> *h)
{
Node<Object> *ptr = h;
Node<Object> *nextPtr;
while (ptr != (Object)NULL)
{
nextPtr = ptr->next;
delete ptr;
ptr = nextPtr;
}
}
int size()
{
return theSize;
}
void print()
{
int i;
Node<Object> *current = head;
for(i=0; i < theSize; ++i){
cout << current->data << " ";
current = current->next;
}
}
bool contains(int x)
{
Node<Object> *current = head;
for (int i = 0; i < theSize; ++i){
if (current->data == x){
return true;
}
current = current -> next;
}
return false;
}
bool add(Object x){
if(!contains(x)){
Node<Object> *new_node = new Node<Object>(x);
new_node->data = x;
new_node->next = head;
head = new_node;
//head->next = new_node;
theSize++;
return true;
}
return false;
}
bool remove(int x)
{
if(contains(x)){
Node<Object> *temp = head;
Node<Object> *prev = NULL;
if(temp != NULL && temp ->data == x){
head = temp->next;
delete temp;
return 0;
}else{
while(temp != NULL && temp->data != x){
prev = temp;
temp = temp->next;
}
if(temp ==NULL){
return 0;
}
prev->next = temp->next;
delete temp;
}
return true;
//theSize--;
}
return false;
}
private:
Node<Object> *head;
int theSize;
};
int main()
{
singleList<int> *lst = new singleList<int>();
lst->add(10);
lst->add(12);
lst->add(15);
lst->add(6);
lst->add(3);
lst->add(8);
lst->add(3);
lst->add(18);
lst->add(5);
lst->add(15);
cout << "The original linked list: ";
lst->print();
cout << endl;
lst->remove(6);
lst->remove(15);
cout << "The updated linked list: ";
lst->print();
cout << endl;
cout << "The number of node in the list: " << lst->size() << endl;
return 0;
}
so the output is supposed to be the following:
The original linked list: 5 18 8 3 6 15 12 10
The update linked list: 5 18 8 3 12 10
The number of node in the list: 6
my output gives the original linked list part but then gives a segmentation fault (core dumped) error. I am not sure where my code is wrong but i think it is in my remove().
Some help will definitely be appreciated.
on line 109 i needed to decrement size.
bool remove(int x)
{
if(contains(x)){
Node<Object> *temp = head;
Node<Object> *prev = NULL;
if(temp != NULL && temp ->data == x){
head = temp->next;
delete temp;
return 0;
}else{
while(temp != NULL && temp->data != x){
prev = temp;
temp = temp->next;
}
if(temp ==NULL){
return 0;
}
prev->next = temp->next;
delete temp;
theSize--;
}
return true;
//theSize--;
}
return false;
}
Answer after second update:
had to fix the remove()
#include <iostream>
using namespace std;
template <typename Object>
struct Node
{
Object data;
Node* next;
Node(const Object &d = Object(), Node *n = (Object)NULL) : data(d), next(n) {}
};
template <typename Object>
class singleList
{
public:
singleList() { init(); }
~singleList() { eraseList(head); }
singleList(const singleList &rhs)
{
eraseList(head);
init();
*this = rhs;
print();
contains(head);
}
void init()
{
theSize = 0;
head = new Node<Object>;
head->next = (Object)NULL;
}
void eraseList(Node<Object> *h)
{
Node<Object> *ptr = h;
Node<Object> *nextPtr;
while (ptr != (Object)NULL)
{
nextPtr = ptr->next;
delete ptr;
ptr = nextPtr;
}
}
int size()
{
return theSize;
}
void print()
{
int i;
Node<Object> *current = head;
for(i=0; i < theSize; ++i){
cout << current->data << " ";
current = current->next;
}
}
bool contains(int x)
{
Node<Object> *current = head;
for (int i = 0; i < theSize; ++i){
if (current->data == x){
return true;
}
current = current -> next;
}
return false;
}
bool add(Object x){
if(!contains(x)){
Node<Object> *new_node = new Node<Object>(x);
new_node->data = x;
new_node->next = head;
head = new_node;
//head->next = new_node;
theSize++;
return true;
}
return false;
}
bool remove(int x){
Node<Object> *pCur = head;
Node<Object> *pPrev = pCur;
while (pCur && pCur->data != x) {
pPrev = pCur;
pCur = pCur->next;
}
if (pCur==nullptr) // not found
return false;
if (pCur == head) { // first element matches
head = pCur->next;
} else {
pPrev->next = pCur->next;
}
// pCur now is excluded from the list
delete pCur;
theSize--;
return true;
}
private:
Node<Object> *head;
int theSize;
};
int main()
{
singleList<int> *lst = new singleList<int>();
lst->add(10);
lst->add(12);
lst->add(15);
lst->add(6);
lst->add(3);
lst->add(8);
lst->add(3);
lst->add(18);
lst->add(5);
lst->add(15);
cout << "The original linked list: ";
lst->print();
cout << endl;
lst->remove(6);
lst->remove(15);
cout << "The updated linked list: ";
lst->print();
cout << endl;
cout << "The number of node in the list: " << lst->size() << endl;
return 0;
}
When I study the DataStructrue in my school, I implemented the Queue.
School's DataStructure class process is below.
student implemnted the DS
student submit in Domjudge
Domjudge score the code based by test cases.
My freind implemented the Queue like below.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
int data;
Node* next;
Node() {}
Node(int e) {
this->data = e;
this->next = NULL;
}
~Node(){}
};
class SLinkedList {
public:
Node* head;
Node* tail;
SLinkedList() {
head = NULL;
tail = NULL;
}
void addFront(int X) {
Node* v = new Node(X); // new Node
if (head == NULL) {
// list is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int removeFront() {
if (head == NULL) {
return -1;
}else{
Node* tmp = head;
int result = head->data;
head = head->next;
delete tmp;
return result;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
void addBack(int X) {
Node* v = new Node(X);
if (head == NULL) {
head = tail = v;
}else {
tail->next = v;
tail = v;
}
}
~SLinkedList() {}
};
class LinkedQ {
public:
int n = 0;
int capacity;
Node* f;
Node* r;
SLinkedList Q;
LinkedQ(int size) {
capacity = size;
f = NULL;
r = NULL;
}
bool isEmpty() {
return n == 0;
}
int size() {
return n;
}
int front() {
return Q.front();
}
int rear() {
return Q.rear();
}
void enqueue(int data) {
if (n == capacity) {
cout << "Full\n";
}else {
Q.addBack(data);
n++;
}
}
};
int main() {
int s, n;
string cmd;
cin >> s >> n;
listQueue q(s);
for (int i = 0; i < n; i++) {
cin >> cmd;
if (cmd == "enqueue") {
int x;
cin >> x;
q.enqueue(x);
}else if (cmd == "size") {
cout << q.size() << "\n";
}else if (cmd == "isEmpty") {
cout << q.isEmpty() << "\n";
}else if (cmd == "front") {
q.front();
}else if (cmd == "rear") {
q.rear();
}
}
}
And I implmented like this (Node class and main are same, So I pass the code)
#include <iostream>
#include <string>
using namespace std;
class Node{...};
class listQueue {
public:
Node* head;
Node* tail;
int capacity;
int n = 0;
listQueue() {
head = NULL;
tail = NULL;
}
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) {
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
~listQueue() {}
};
test cases are just enqueue
but my friend is correct, and my code has occured memory over error.
So I check the usage of memory in Domjudge, My friend code and My code has very big gap in memory usage.
Why these two codes have memory usage gap big?
P.S I can't speak English well. If there is something you don't understand, please tell me.
First, rear is incorrect. It checks head and return tail. It happens to correct when you first set head=tail=v but it might get wrong later.
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
Check the if statement below:
v is leaked if queue is full in enqueue in your implementation.
Don't use NULL in C++. You may refer to NULL vs nullptr (Why was it replaced?).
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) { // You're leaking v;
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
string name;
int age, height, weight;
Person(string name = "empty", int age = 0, int height = 0, int weight = 0) {
this->name = name;
this->age = age;
this->height = height;
this->weight = weight;
}
Person operator = (const Person &P) {
name = P.name;
age = P.age;
height = P.height;
weight = P.weight;
return *this;
}
void setAge(int a){
age = a;
}
int getAge(){
return age;
}
friend ostream& operator<<(ostream& os, const Person& p);
};
ostream& operator<<(ostream& os, Person& p) {
os << "Name: " << p.name << " " << "Age: " << p.age << " " << "Height: " << p.height << " " << "Weight: " << p.weight << "\n";
return os;
};
class Node {
public:
Person* data;
Node* next;
Node(Person*A) {
data = A;
next = nullptr;
}
};
class LinkedList {
public:
Node * head;
LinkedList() {
head = nullptr;
}
void InsertAtHead(Person*A) {
Node* node = new Node(A);
node->next = head;
head = node;
}
void InsertAtEnd(Person*A) {
if (head == nullptr) {
InsertAtHead(A);
}
else {
Node* node = new Node(A);
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = node;
}
}
void InsertAtPosition(Person*A, int pos) {
if (head == nullptr) {
InsertAtHead(A);
}
else {
Node* node = new Node(A);
Node* temp = head;
for (int i = 1; i < pos - 1; i++) { temp = temp->next; }
node->next = temp->next;
temp->next = node;
}
}
void DeleteByValue(string search_name) {
Node* temp = head;
Node* prev = nullptr;
while (temp != nullptr) {
if (temp->data->name == search_name) {
if (prev != nullptr) {
prev->next = temp->next;
}
else {
head = temp->next;
}
delete temp;
temp = nullptr;
}
else {
prev = temp;
temp = temp->next;
}
}
}
void DeleteFromHead() {
if (head != nullptr) {
Node* temp = head;
head = head->next;
delete temp;
}
}
void DeleteFromEnd() {
Node* prev = nullptr;
Node* temp = head;
if (head == nullptr) { cout << "Nothing to delete" << endl; }
else if (head->next == nullptr) { DeleteFromHead(); }
else {
while (temp->next != nullptr) {
prev = temp;
temp = temp->next;
}
prev->next = nullptr;
delete temp;
}
}
void DeleteAtPosition(int pos) {
Node* prev = nullptr;
Node* temp = head;
if (head == nullptr) { cout << "Nothing to delete" << endl; }
else if (pos == 1) { DeleteFromHead(); }
else {
for (int i = 1; i < pos; i++) {
prev = temp;
temp = temp->next;
}
prev->next = temp->next;
delete temp;
}
}
void UpdateAtPosition(Person*A, int pos) {
if (head == nullptr) { cout << "No element in the list"; return; }
if (pos == 1) { head->data = A; }
else {
Node* temp = head;
for (int i = 1; i < pos; i++) {
temp = temp->next;
}
temp->data = A;
}
}
void UpdateByValue(string name, int newAge) {
Node* temp = head;
Person* p = new Person();
while(temp != nullptr){
if(temp->data->name == name){
p->setAge(newAge);
}else{
temp = temp->next;
}
}
}
void Print() {
Node* temp = head;
while (temp != nullptr) {
cout << *(temp->data);
temp = temp->next;
}
cout << endl;
}
};
int main() {
LinkedList* list = new LinkedList();
list->InsertAtHead(new Person("Samantha", 20, 63, 115)); list->Print();
list->InsertAtEnd(new Person("Chris", 19, 70, 200)); list->Print();
list->DeleteByValue("Chris"); list->Print();
list->UpdateByValue("Samantha", 21); list->Print();
return 0;
}
I am new to C++ so excuse any poorly written code, but I am trying to use the function UpdateByValue to update the age of Samantha. It may look very wrong right now, but I have tried 20 different things and cannot figure out what I am doing wrong. I used to go to school at a community college where I learned Java so Im catching up to everyone in C++. A lot of it is similar but I struggle with little things like this. Could anyone explain to me how to fix the UpdateByValue function so that it will change the age of my Person object of choice? I want to be able to type the name as the first parameter and change the age of that person with the second parameter. If something is unclear and needs more explaining please let me know, I just need help. Thanks in advance, and please feel free to give any other constructive criticism. I am trying to get as good as I can.
Let's take a walk through UpdateByValue. I'll comment as we go.
void UpdateByValue(string name, int newAge) {
Node* temp = head;
Person* p = new Person();
while(temp != nullptr){ // keep looking until end of list
if(temp->data->name == name){ // found node with name
p->setAge(newAge); // update a different node
// never advance node so we can't exit function
}else{
temp = temp->next;
}
}
}
Try instead
void UpdateByValue(string name, int newAge) {
Node* temp = head;
// Person * p is not needed
while(temp != nullptr){ // keep looking until end of list
if(temp->data->name == name){ // found node with name
temp->data->setAge(newAge); // update the found node
return; // done searching. Exit function
}else{
temp = temp->next;
}
}
}
This is a very simple program that implements a stack using a linked list. Kindly help me figure out the logical bug that makes the program crash on run.
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
head->next = new Node(*(s.head->next));
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
this->head->next = new Node(*(s.head->next));
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "\n\nNo elements to pop\n\n";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "\n\nNo elements in the stack\n\n";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
This is the trouble-maker fuction:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "\n\nFlushing s:\n";
s.flush();
system("pause");
return 0;
}
I have implemented my own copy constructor and the copy assignment operator. I don't understand why it crashes on run. On flushing it displays garbage values before crashing.
The problem is your copy assignment operator. Consider:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
Everything works fine until you return from the function, at which point the destructor for s2 is called. The destructor calls flush(), which deletes all stack elements of s2. In your copy assignment operator (and copy constructor, at that), you create two nodes: head and head->next; the rest of the nodes are shared between the two stacks, so after s2 has been deleted, s1.head->next->next points to a node that has been deleted, but you still try to access it.
The solution is to have the copy assignment operator (and the copy constructor) create a proper deep copy of the stack, not just the first two elements, like this (also takes care of self assignment):
LLStack& LLStack::operator=(const LLStack& s) {
if (this==&s) return *this; // self assignment
flush(); // avoid memory leak
head = new Node(*s.head);
Node* s_ptr = s.head;
Node* t_ptr = head;
while (s_ptr->next) {
t_ptr->next = new Node(*s_ptr->next);
s_ptr = s_ptr->next;
t_ptr = t_ptr->next;
}
return *this;
}
Remember that the copy constructor should do the same.