What is wrong with my Remove Function?
In my 

> int Queue::remove(int x)

 member function of my Queue class that you will find below, the user can enter a number and if the number is found in the Queue, the node containing the number is removed and the number in question is returned. If the number is not found "number not found" is output and number zero is returned. However, when the number is not found the program just crashes.
Also, even if the output did work, it looks a bit weird outputting "0 is removed...etc" when actually what I mean is that the number was not found and not that the number "0" was found and removed..    

    #include <iostream>
    #include <string>
    #include <cassert>
    
    using namespace std;
    
    class Dnode
    {
    	public:
    	   Dnode(int);
    	   int	n;
    	   Dnode*	l, *r;
    };
    
    Dnode::Dnode(int tx)
    {
    	n = tx;
    	l = r = NULL;
    }
    
    class Queue // reminder: insertions at the rear, deletions at the front
    {
    	public:
    	   Queue();
    	   void enqueue(int x);
    	   int dequeue();
    	   bool empty() const;
    	   void display() const;
    	   Queue(const Queue&);             // copy constructor
    	   ~Queue();                        // destructor
    	   Queue& operator= (const Queue&); // assignment operator
    	   void displayrev() const;
    	   int remove(int);
    
    
        private:
    	   Dnode*	front, *back;
    	   void copy(Dnode*);
    	   void free();
    
    };
    
    Queue::Queue()
    {
    	front = back = NULL;
    }
    
    
    void Queue::enqueue(int x)
    {
    	Dnode*	d = new Dnode(x);
    	if (empty())
    		front = back = d;
    	else
    	{
    		back->r = d; // makes last dnode's right hand point to the new one
    		d->l = back; // makes new dnode's left hand point to the previous last one
    		back = d;    // makes back pointer point to the new last dnode
    	}
    }
    
    int Queue::dequeue()
    {
    	assert(! empty());
    	Dnode*	temp = front;
    	front = front->r;  // moves front pointer one dnode to the right
    	if (front == NULL) // if there was only one dnode in the queue
    		back = NULL;   // now both front and back pointers are set to NULL
    	else	front->l = NULL;
    	int	x = temp->n;
    	delete temp;
    	return x;
    }
    
    
    bool Queue::empty() const
    {
    	return front == NULL;
    }
    
    void Queue::display() const
    {
    	for (Dnode* d = front; d != NULL; d = d->r) //front to rear
    		cout << d->n << " ";
    	cout << endl;
    }
    
    void Queue::displayrev() const
    {
    	for (Dnode* d = back; d != NULL; d = d->l) // rear to front
    		cout << d->n << " ";
    	cout << endl;
    }
    
    void Queue::copy(Dnode* dn) //"dn" will be "Front" of Queue being copied
    {
    	front=back=NULL;
    
    	if(dn!=NULL)
    	{
    		while(dn->r!=NULL)
    		{
    			enqueue(dn->n);
    			dn=dn->r;
    		}
    		enqueue(dn->n);
    	}
    }
    
    Queue::Queue(const Queue& x)
    {
    	copy(x.front);
    }
    
    void Queue::free()
    {
    	Dnode* temp=front;
    
    	while(front!=back)
    	{
    		front=front->r;
    	    delete temp;
    	    temp=front;
    	}
    	delete temp;
    
    	front=back=temp=NULL;
    }
    
    Queue::~Queue()
    {
    	cout << "Destructor called!"<<endl<<endl;
    	free();
    }
    
    Queue& Queue::operator= (const Queue& x)
    {
    	if(this!=&x)
    	{
    		free();
    	    copy(x.front);
    	}
    	return *this;
    }
    
    int Queue::remove(int x) //<--- Here we are...
    {
    	Dnode* temp=front;
    
    	if(front->n==x) // if the node being deleted is the first node
    	{
    		front=front->r;
    		if(front==NULL) // if there is only one node in the Queue
    		{
    			back=NULL;
    		}
    		else
    		{
    			front->l=NULL;
    		}
    		delete temp;
    		return x;
    	}
    
            Dnode* pre;
    
    	while(temp!=NULL && temp->n!=x) // order of conditions is important!
    	{
    		pre=temp;
    		temp=temp->r;
    	}
    
    	if(back->n==x) // if the node being deleted is the last node
    	{
    		back=pre;
    		back->r=NULL;
    		delete temp;
    		return x;
    	}
    
    	if(temp->n==x) // deleting from the middle
    	{
    		pre->r=temp->r;
    		temp->r->l=pre;
    		delete temp;
    		return x;
    	}
    
    	cout<<"Number not found! ";// if number is not found, function should
    	return 0;                  // return number 0, but it doesn't, instead
    }                              // it crashes the program
                                   // check out my output for this function in main() below                 
                                   // as well..
    int main()
    {
    	Queue	q;
    
    	if (q.empty()) cout << endl<<"Queue \"q\" is empty" << endl;
    
    	for (int i = 0; i < 10; i++) q.enqueue(i);
    
    	cout<<endl<<"Queue \"q\" is now populated"<<endl<<endl<<"Queue \"q\" : ";
    
    	q.display();
    
    	int	x = q.dequeue();
    
    	cout <<endl<<"First element of \"q\" has been removed from the front" << endl;
    
    	cout << endl<<"Element removed is " << x << endl;
    
    	cout<<endl<<"Queue \"q\" : ";
    
    	q.display();
    
    	Queue q1(q);
    
    	cout<<endl<<"Queue \"q1\" has been created as a copy of \"q\""<<endl<<endl;
    
    	cout<<"Queue \"q1\" : ";
    
    	q1.display();
    
    	Queue q2=q1;
    
    	cout<<endl<<endl<<"Queue \"q1\" has been assigned to new Queue \"q2\""<<endl<<endl;
    
    	cout<<"Queue \"q2\" : ";
    
    	q2.display();
    
    	q1=q1;
    
    	cout<<endl<<endl<<"\"q1\" has been assigned to itself and what we get is: ";
    
    	q1.display();
    
            cout<<endl<<"\"q1\" displayed in reverse: ";
    
    	q1.displayrev();
    
    	cout<<endl<<"type in a number to remove from \"q1\": ";
    
    	int y;
    
    	while(cin>>y)
    	{
    		cout<<endl<<q1.remove(y)<<" has been removed from \"q1\" "<<"type in              
                    another one or q to quit: ";
    	}
    
    	/*
    	if the number is not found, the above "cout" should look like this :
    
    	"Number not found! 0 has been removed from "q1" type in another one or q to quit: " 
    
         However, this is not the case and the program crashes when number is not found
    	*/
    
    
    	cout<<endl<<"Queue \"q1\" : ";
    
    	q1.display();
    
    	cout<<endl;
    }
What is wrong with my Remove Function?
===

In my 

> int Queue::remove(int x)

 member function of my Queue class that you will find below, the user can enter a number and if the number is found in the Queue, the node containing the number is removed and the number in question is returned. If the number is not found "number not found" is output and number zero is returned. However, when the number is not found the program just crashes.
Also, even if the output did work, it looks a bit weird outputting "0 is removed...etc" when actually what I mean is that the number was not found and not that the number "0" was found and removed..    

    #include <iostream>
    #include <string>
    #include <cassert>
    
    using namespace std;
    
    class Dnode
    {
    	public:
    	   Dnode(int);
    	   int	n;
    	   Dnode*	l, *r;
    };
    
    Dnode::Dnode(int tx)
    {
    	n = tx;
    	l = r = NULL;
    }
    
    class Queue // reminder: insertions at the rear, deletions at the front
    {
    	public:
    	   Queue();
    	   void enqueue(int x);
    	   int dequeue();
    	   bool empty() const;
    	   void display() const;
    	   Queue(const Queue&);             // copy constructor
    	   ~Queue();                        // destructor
    	   Queue& operator= (const Queue&); // assignment operator
    	   void displayrev() const;
    	   int remove(int);
    
    
        private:
    	   Dnode*	front, *back;
    	   void copy(Dnode*);
    	   void free();
    
    };
    
    Queue::Queue()
    {
    	front = back = NULL;
    }
    
    
    void Queue::enqueue(int x)
    {
    	Dnode*	d = new Dnode(x);
    	if (empty())
    		front = back = d;
    	else
    	{
    		back->r = d; // makes last dnode's right hand point to the new one
    		d->l = back; // makes new dnode's left hand point to the previous last one
    		back = d;    // makes back pointer point to the new last dnode
    	}
    }
    
    int Queue::dequeue()
    {
    	assert(! empty());
    	Dnode*	temp = front;
    	front = front->r;  // moves front pointer one dnode to the right
    	if (front == NULL) // if there was only one dnode in the queue
    		back = NULL;   // now both front and back pointers are set to NULL
    	else	front->l = NULL;
    	int	x = temp->n;
    	delete temp;
    	return x;
    }
    
    
    bool Queue::empty() const
    {
    	return front == NULL;
    }
    
    void Queue::display() const
    {
    	for (Dnode* d = front; d != NULL; d = d->r) //front to rear
    		cout << d->n << " ";
    	cout << endl;
    }
    
    void Queue::displayrev() const
    {
    	for (Dnode* d = back; d != NULL; d = d->l) // rear to front
    		cout << d->n << " ";
    	cout << endl;
    }
    
    void Queue::copy(Dnode* dn) //"dn" will be "Front" of Queue being copied
    {
    	front=back=NULL;
    
    	if(dn!=NULL)
    	{
    		while(dn->r!=NULL)
    		{
    			enqueue(dn->n);
    			dn=dn->r;
    		}
    		enqueue(dn->n);
    	}
    }
    
    Queue::Queue(const Queue& x)
    {
    	copy(x.front);
    }
    
    void Queue::free()
    {
    	Dnode* temp=front;
    
    	while(front!=back)
    	{
    		front=front->r;
    	    delete temp;
    	    temp=front;
    	}
    	delete temp;
    
    	front=back=temp=NULL;
    }
    
    Queue::~Queue()
    {
    	cout << "Destructor called!"<<endl<<endl;
    	free();
    }
    
    Queue& Queue::operator= (const Queue& x)
    {
    	if(this!=&x)
    	{
    		free();
    	    copy(x.front);
    	}
    	return *this;
    }
    
    int Queue::remove(int x) //<--- Here we are...
    {
    	Dnode* temp=front;
    
    	if(front->n==x) // if the node being deleted is the first node
    	{
    		front=front->r;
    		if(front==NULL) // if there is only one node in the Queue
    		{
    			back=NULL;
    		}
    		else
    		{
    			front->l=NULL;
    		}
    		delete temp;
    		return x;
    	}
    
            Dnode* pre;
    
    	while(temp!=NULL && temp->n!=x) // order of conditions is important!
    	{
    		pre=temp;
    		temp=temp->r;
    	}
    
    	if(back->n==x) // if the node being deleted is the last node
    	{
    		back=pre;
    		back->r=NULL;
    		delete temp;
    		return x;
    	}
    
    	if(temp->n==x) // deleting from the middle
    	{
    		pre->r=temp->r;
    		temp->r->l=pre;
    		delete temp;
    		return x;
    	}
    
    	cout<<"Number not found! ";// if number is not found, function should
    	return 0;                  // return number 0, but it doesn't, instead
    }                              // it crashes the program
                                   // check out my output for this function in main() below                 
                                   // as well..
    int main()
    {
    	Queue	q;
    
    	if (q.empty()) cout << endl<<"Queue \"q\" is empty" << endl;
    
    	for (int i = 0; i < 10; i++) q.enqueue(i);
    
    	cout<<endl<<"Queue \"q\" is now populated"<<endl<<endl<<"Queue \"q\" : ";
    
    	q.display();
    
    	int	x = q.dequeue();
    
    	cout <<endl<<"First element of \"q\" has been removed from the front" << endl;
    
    	cout << endl<<"Element removed is " << x << endl;
    
    	cout<<endl<<"Queue \"q\" : ";
    
    	q.display();
    
    	Queue q1(q);
    
    	cout<<endl<<"Queue \"q1\" has been created as a copy of \"q\""<<endl<<endl;
    
    	cout<<"Queue \"q1\" : ";
    
    	q1.display();
    
    	Queue q2=q1;
    
    	cout<<endl<<endl<<"Queue \"q1\" has been assigned to new Queue \"q2\""<<endl<<endl;
    
    	cout<<"Queue \"q2\" : ";
    
    	q2.display();
    
    	q1=q1;
    
    	cout<<endl<<endl<<"\"q1\" has been assigned to itself and what we get is: ";
    
    	q1.display();
    
            cout<<endl<<"\"q1\" displayed in reverse: ";
    
    	q1.displayrev();
    
    	cout<<endl<<"type in a number to remove from \"q1\": ";
    
    	int y;
    
    	while(cin>>y)
    	{
    		cout<<endl<<q1.remove(y)<<" has been removed from \"q1\" "<<"type in              
                    another one or q to quit: ";
    	}
    
    	/*
    	if the number is not found, the above "cout" should look like this :
    
    	"Number not found! 0 has been removed from "q1" type in another one or q to quit: " 
    
         However, this is not the case and the program crashes when number is not found
    	*/
    
    
    	cout<<endl<<"Queue \"q1\" : ";
    
    	q1.display();
    
    	cout<<endl;
    }