0

I need some help. Basically, I'm learning Data structures & Algorithms, and wrote a basic singly list code, but there is a problem of a runtime exception thrown due to the list destructor (which my professor taught).

#include "list.h"
#include <iostream>
using namespace std;

list::list() : head(NULL), tail(NULL) {}

Node* list::get_head() const { return head; }

Node* list::get_tail() const { return tail; }

bool list::isEmpty() const {
    if (head == NULL)
        return true;
    return false;
}

void list::insert_end(int value) {
    Node* p = new Node(value);  //p->Data = value;
    if (isEmpty())
        head = p;
    else
        tail->next = p;
    tail = p;
}

list::~list() {
    if (isEmpty())
        return;
    else
        cout << "Not empty\n";

    cout << "Entering ~" << endl;
    Node* p = head;
    Node* q = head->next;
    while (p != NULL)
    {
        cout << "Deleting:" << p->Data << "\t\t";
        if (p->next == NULL) {

            cout << "NOW" << endl;
        }
        delete p;
        p = q;
        if (p != NULL)
            q = q->next;
    }
    cout << "Leaving ~" << endl;
}
#include <iostream>
#include "list.h"

void Display_headTail(list & list) {
    if (!list.isEmpty())
        cout << "Head:" << list.get_head()->Data
        << "\tTail:" << list.get_tail()->Data << endl;
}

int main() {
    list mylist;
    mylist.insert_end(1);
    mylist.insert_end(2);
    mylist.insert_end(3);
    mylist.insert_end(4);
    mylist.insert_end(5);
    mylist.Display_list();
    Display_headTail(mylist);//pass by Value
}

image

NOTE: Display_headTail() takes list by Value, and immediately after its destructor is called, and after that the last line of code is executed giving the error:

image

And in case the order of instructions changed to:

mylist.Display_list();
Display_headTail(mylist);//pass by Value

Then the following error occurs:

image

NOTE: The destructor is called twice (no idea why) along with the exception:

image

Finally, if I pass the list by reference, the program works perfectly fine.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 2
    [What is The Rule of Three?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). If you instructor taught you that (odd) destructor, they should also have taught you about The Rule of Three. Follow the link. – WhozCraig Oct 25 '22 at 12:09
  • `Display HeadTail() takes list by Value` - you have to define custom [copy constructor](https://en.cppreference.com/w/cpp/language/copy_constructor) and [copy assignment operator](https://en.cppreference.com/w/cpp/language/copy_assignment) which would clone underlying pointers list with links to the cloned items if you want your class to be copyable. – dewaffled Oct 25 '22 at 12:15
  • To clarify what goes wrong in the pass by value scenario: the compiler generated a copy constructor to initialise the argument to `Display_headTail`. It can do this if one isn't specified and all class members are copyable, in this case simply creating a new `list` with the same head and tail. This copy is destroyed at the end of the function call, after which `mylist`'s pointers are dangling. Dereferencing them is the "access violation", attempting to `delete` them again is a "double free" exception, which happens when `mylist` is destroyed at the end of `main`. – sigma Oct 25 '22 at 15:23
  • "*`Display_headTail()` takes list by Value*" - in the code shown, `Display_headTail()` takes the list by reference, which is what it should be doing. Though, it really should be a const reference instead: `void Display_headTail(const list & list)` – Remy Lebeau Oct 25 '22 at 16:31

0 Answers0