Aryan Arora
Aryan Arora

Reputation: 45

Threads on xcode while compiling the c++ code

so I was trying to build this project on deque using the doubly linked list. but when I build it. it says build but gives threads and doesn't give the output as required. I have re-implemented the major problem(copy constructor) and all the functions again and again but then it still gives me new threads every time.

this is the header file.

#pragma once
#include <stdexcept>
using namespace std;

class Node
{
public:

    int data;
    Node* next;
    Node* previous;
    Node();
    Node(const int &x);

};

class Deque
{
public:

    Deque();
    Deque(const Deque &d);
    Deque &operator= (const Deque &d);
   ~Deque();
    void insertFront(const int &x);
    void insertBack(const int &x);
    int removeFront();
    int removeBack();
    int  peekFront();
    int  peekBack();
    bool empty() const;
    int size()const;
    friend ostream&  operator << (ostream &out, const Deque &d);


private:

    Node* front;
    Node* rear;

};

this will be the .cpp (implementation file.)

//
//  Deque_cmpt225.cpp
//  Deque_cmpt225
//
//  Created by Aryan Arora on 2017-10-09.
//  Copyright © 2017 Aryan Arora. All rights reserved.
//

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

Node:: Node() 
{
    previous = nullptr;
    next = nullptr;
    data = 0;
}

Node:: Node(const int &x)
{
    Node();
    data = x;
}


Deque:: Deque() //Empty Deque.
{
    front = nullptr;
    rear = nullptr;

}

Deque:: ~Deque()
{
    if (this->empty())
        return;
    else{
    Node* temp;
    while (this->front->next != nullptr){
        temp = this->front;
        this->front = this->front->next;
        delete temp;

    }
        temp = this->front;
        this->front = nullptr;
        this->rear = nullptr;
        delete temp;

    }


}


Deque:: Deque (const Deque &d) //Copy Constructor
{
    if (d.empty()) //Deque is empty.
    {
        return;
    }
    Node* temp = d.front;
    int x;
    if (temp->next == nullptr) //Deque of just one node
    {
        x = temp->data;
        Node *n1 = new Node (x);
        n1->next = nullptr;
        n1->previous = nullptr;
        this->front = n1;
        this->rear = n1;

    }
    else //Deque has more than one node
    {
        while (temp!= nullptr)
        {
            this->insertBack(temp->data);
            temp = temp -> next;
        }


    }

}



Deque& Deque:: operator=(const Deque &d) //============================check again
{
    if (this == &d)
        return *this;
    else
    {
        this->~Deque();                                //DELETING THE DEQUE
        Node* temp = d.front;     //COPYING EACH NODE
        while (temp != NULL)
        {
            this->insertBack(temp->data);        //INSERTING AT THE BACK
            temp = temp->next;                  //POINTING TEMP TO NEXT NODE
        }

    }
    return *this;


}

void Deque:: insertFront(const int &x)
{

    Node* temp = new Node(x);
    temp->next = nullptr;
    temp->previous = nullptr;
    if (empty())
    {
        this->front = temp;
        this->rear = temp;
    }
    else
    {
        temp->next = this->front;
        temp->previous = nullptr;
        this->front->previous = temp;
        this->front = temp;
    }

}

void Deque:: insertBack(const int &x)
{
    Node* temp = new Node(x);
    temp->next = nullptr;
    temp->previous = nullptr;
    if (empty())
    {
        this->front = temp;
        this->rear = temp;
    }
    else
    {
        temp->next = nullptr;
        temp->previous = this->rear;
        this->rear->next = temp;
        this->rear = temp;

    }

}

int Deque:: removeFront()
{
    if (empty()) //=================runtime error
    {
        throw std::runtime_error("The que is empty.");
    }
    else{
    Node* temp;
    temp = this->front;
    int x = temp->data;

    if ( this->front->next != nullptr )
    {
        this->front = this->front->next;
        this->front->previous = nullptr;
    }
    else
    {
        this->front = nullptr;
        this->rear = nullptr;
    }
    delete temp;

    return x;
    }

}


int Deque:: removeBack()
{
    if (empty()) //=================runtime error
    {
        throw std::runtime_error("The que is empty.");

    }
    else{
    Node* temp = this->rear;
    int x = temp->data;

    if ( this->rear->previous != nullptr )
    {
        this->rear = this->rear->previous;
        this->rear->next = nullptr;
    }
    else
    {
        this->rear = nullptr;
        this->front = nullptr;
    }
    delete temp;

    return x;
    }

}

int Deque:: peekFront()
{
    if (empty()) //=================runtime error
    {
        throw std::runtime_error("The que is empty.");
    }
    else
    {
        return this->front->data;
    }

}
int Deque:: peekBack()
{
    if (empty()) //=================runtime error
    {
        throw std::runtime_error("The que is empty.");
    }
    else
    {
        return this->rear->data;
    }
}

bool Deque:: empty() const
{
    if (this->front == nullptr && this->rear == nullptr)
        return true;
    else
        return false;
}


int Deque:: size() const
{
    Node* temp = this->front;
    int count = 0;
    while (temp != nullptr)
    {
        count++;
        temp = temp->next;
    }
    return count;

}

ostream&  operator << (ostream &out, const Deque &d)
{
    Node* temp = d.front;
    out << "NULL -> ";
    while (temp != nullptr)
    {
        out << temp->data << " <-> ";
        temp= temp->next;


    }

    out << "<- NULL" << endl;
    return out;

}

thanks in advance.

Upvotes: 2

Views: 55

Answers (1)

Brandon
Brandon

Reputation: 23500

Your code has many problems..

Your Node constructor doesn't delegate properly..

Node::Node() 
{
    previous = nullptr;
    next = nullptr;
    data = 0;
}

Node::Node(const int &x)
{
    Node();  //Creates a temporary node that gets destroyed immediately..
    data = x;
}

It's much simpler if you change it to:

Node::Node() : Node(0) //Delegating constructor.
{
}

Node::Node(const int &x) : previous(nullptr), next(nullptr), data(x)
{
}

This point isn't really a problem, but worth mentioning.. You keep setting the Node pointers to nullptr right after construction. This is not necessary because your constructor already does that..

Node* temp = new Node(x);
temp->next = nullptr;  //Not needed anymore with the above fixes.
temp->previous = nullptr;  //Not needed anymore with the above fixes.

You never initialize your variables in the copy constructor.. In your constructor, you have (I changed it, but it has the same meaning):

Deque::Deque() : front(nullptr), rear(nullptr)
{
}

But in your copy constructor, you have:

Deque::Deque(const Deque &d)
{
    //Other code here.. You never initialized front and rear to nullptr..
}

You never set front and rear to nullptr so empty() returns false since they are a "random" uninitialized value.. Then in insertBack you go on to access this and boom.. Access Violation.

To fix it, you do:

Deque::Deque(const Deque &d) : front(nullptr), rear(nullptr)
{
   //Other code here..
}

Next issue is that your copy assignment operator is calling the destructor!

Deque& Deque::operator=(const Deque &d)
{
    if (this == &d)
        return *this;
    else
    {
        this->~Deque() //YOU CANNOT DO THIS.. Create a private member function for cleaning up.. Then call that function in your destructor and call that function here.. You cannot invoke the destructor like this.
    }

    //....
}

Upvotes: 1

Related Questions