/* CSC 123/252 Assignment This program in C++ implements a simple stack data structure using a linked list of "cells". Despite the fact that there is a destructor in the Stack struct (class) that deletes each cell of the stack, and the fact that the Stack destructor is called at the end of the test() function (the Stack is allocated on the local runtime stack frame of test()), there are still memory errors. Your assignment is to: 1. pinpoint where the errors occur. 2. Rewrite the program using std::unique_ptr and std::make_unique. **YOUR PROGRAM MUST NOT USE ANY RAW POINTERS**, not even nullptr. You may use the default value for types, which in modern C++ is just "{}". All calls to "new" must be replaced with calls to std::make_unique. You must implement at the least the push and pop functions, but move_back is optional. You must prove that there's no memory leak in your program. Use a system monitor. In the Linux VM for the class your can find a "task manager" program under applications->system. This is not intended to be an overly difficult assignment, and to help you out, I will provide the new version of the cell class: template struct cell { T item; unique_ptr> next; cell(T i) { item=i; next = {}; } cell(T i, unique_ptr>&& n) { item=i; next=move(n); } };// class for a single linked-list cell */ #include #include using namespace std; // compile with c++11 or later // struct for a stack data structure using a linked list template struct cell { T item; cell* next; cell(T i) {item=i;} cell(T i, cell* n) { item=i; next=n; } };// class for a single linked-list cell template struct Stack // struct that manages pointer to stack. { cell* front; // pointer to first cell Stack() { front={}; } operator bool() {return front; } // can use stack as true if not null void push(T x) { front = new cell(x,front); }//push T pop() { if (front) { T answer = front->item; front = front->next; return answer; } else return {}; // return the default value of T }//pop // optional: move the front cell to the end of the stack // a-b-c-d becomes b-c-d-a void move_back() { if (!front) return; auto current = front; while(current->next) current = current->next; current->next = front; front = front->next; current->next->next = {}; } // implementing this function is optional (it's quite hard) //destructor ~Stack() { while(front) { auto temp = front; front = front->next; delete(temp); } }//destructor called by delete if on heap, or when popped if on runtime stack. };//Stack void test() { Stack S; // this Stack struct is stack-allocated. for(int x:{2,4,6,8,10}) S.push(x); S.move_back(); // are you sure this works? while (S) cout << S.pop() << " "; cout << endl; //while (S) S.pop(); // use version without cout to test memory leaks // destructor for S called when function ends } int main() { /*while(1)*/ test(); // is there a memory leak in your program? return 0; // observe with system monitor (task manager) }