1 Replies - 1153 Views - Last Post: 14 October 2013 - 08:47 PM Rate Topic: -----

#1 teg01   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 11-October 13

Having trouble with my destructor. Receiving error "Pointer freed.

Posted 14 October 2013 - 08:23 PM

My program is supposed to be a self written QUEUE template along with a driver to test out the QUEUE. My QUEUE is working fine and so is my driver. It is able to test everything out perfectly. However, as soon as I put my destructor in the QUEUE template I get the error

malloc: *** error for object 0x100103ad0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug


I had a similar issue before but that only occurred when I ran my .h file with my test driver. When I ran it with my app I did not receive that error. However, since I'm solely using my driver to test out my QUEUE template I have to figure out a way to get past this error.

I'm not exactly understanding the error. It's saying that the pointer being freed was not allocated? Shouldn't the pointer be allocated as soon as my program runs by the constructor?


QUEUE.h
#ifndef Queue_h
#define Queue_h

#include <iostream>

template <class DataType>
struct Node
{
  DataType data;
  Node <DataType> *next;
};

template <class DataType>
class Queue
{
public:
  Queue(); // default constructor
  Queue (const Queue<DataType> &); // copy constructor
  ~Queue(); // destructor
  bool isEmpty() const;
  void push (const DataType & parameter);
  bool peek (DataType & parameter) const;
  bool pop (DataType & parameter);
  void makeEmpty();
  
private:
  Node<DataType> *front;
  Node<DataType> *end;
};

template <class DataType>
Queue<DataType>::Queue()
: front(0), end(0)
{
}

template <class DataType>
Queue<DataType>::Queue(const Queue<DataType>& copy)
: front(0), end(0)
{
  Node<DataType>* p;
  for (p = copy.front; p; p = p->next)
  {
    Node<DataType>* node = new Node<DataType>;
    node->data = p->data;
    node->next = 0;
    if (end) end->next = node;
    else front = node;
    end = node;
  } }

template <class DataType>
Queue<DataType>::~Queue()
{
  Node<DataType>* p;
  while (front)
  {
    p = front->next;
    delete front;
    front = p;
  } }

template <class DataType>
bool Queue<DataType>::isEmpty() const {return 0 == front;}

template <class DataType>
void Queue<DataType>::push(const DataType& parameter)
{
  Node<DataType>* node = new Node<DataType>;
  node->data = parameter;
  node->next = 0;
  if (end) end->next = node;
  else front = node;
  end = node;
}

template <class DataType>
bool Queue<DataType>::peek(DataType& parameter) const
{
  if (0 == front) return false; // failed
  parameter = front->data;
  return true; // success
}

template <class DataType>
bool Queue<DataType>::pop(DataType& parameter)
{
  if (0 == front) return false; // failed
  parameter = front->data;
  Node<DataType>* p = front->next;
  delete front;
  front = p;
  if (front == 0) end = 0;
  return true; // success
}

template <class DataType>
void Queue<DataType>::makeEmpty()
{
  end = 0;
  Node<DataType>* p;
  while (front)
  {
    p = front->next;
    delete front;
    front = p;
  } }

#endif 



testDriver.cpp
#include "Queue.h"
#include "Queue.h" // to test #ifndef
#include <cassert>
#include <iostream>

using namespace std;

int main()
{  
  Queue<double> test;
  
  // first test, constructor
  cout << "1. Testing constructor- ";
  assert(test.isEmpty() == true);
  cout << "Constructor working successfully" << endl;
  
  // second test, push
  test.push(1);
  cout << "2. Testing push- ";
  assert(test.isEmpty() == false);
  cout << "Push test successful" << endl;
  
  // third test, peek
  double var;
  cout << "3. Testing peek- ";
  assert(test.peek(var) == 1);
  cout << "Peek test successful" << endl;
  
  // fourth test, pop
  cout << "4. Testing pop- ";
  assert(test.isEmpty() == false);
  cout << "Queue is not empty" << endl;
  test.pop(var); // after pop
  assert(test.isEmpty() == true);
  cout << "   Queue is now empty" << endl;
  
  // fifth test, makeEmpty
  cout << "5. Testing makeEmpty- ";
  test.push(1), test.push(2), test.push(3);
  assert(test.isEmpty() == false);
  cout << "Queue is not empty" << endl;
  test.makeEmpty();
  assert(test.isEmpty() == true);
  cout << "   Queue is now empty" << endl;
  
  test.push(1);
  // const object copy testing with assignment UPON declaration
  {
    const Queue <double> copy = test;
    
    // first test, constructor
    cout << endl;
    cout << "object copy testing with assignment UPON declaration" << endl;
    assert(copy.isEmpty() == false);

    double var;
    assert(copy.peek(var) == 1);
   
    cout << "object copy testing with assignment UPON declaration WORKING" << endl;
    // copy.push(1); FAILED
    // copy.pop(var); FAILED
    // copy.makeEmpty(); FAILED

  }
  
  // object copy testing with assignment AFTER declaration
  {
    Queue <double> copy;
    copy = test;
    
    // first test, constructor
    cout << endl;
    cout << "object copy testing with assignment AFTER declaration" << endl;
    assert(copy.isEmpty() == false);
    assert(copy.isEmpty() == false);
    
    double var;
    assert(copy.peek(var) == 1);
    
    assert(copy.isEmpty() == false);
    
    copy.push(1), copy.push(2), copy.push(3);
    assert(copy.isEmpty() == false);
    copy.makeEmpty();
    assert(copy.isEmpty() == true);
    cout << "bject copy testing with assignment AFTER declaration WORKING" << endl;
  }
}



Is This A Good Question/Topic? 0
  • +

Replies To: Having trouble with my destructor. Receiving error "Pointer freed.

#2 eker676   User is offline

  • Software Engineer
  • member icon

Reputation: 379
  • View blog
  • Posts: 1,833
  • Joined: 18-April 09

Re: Having trouble with my destructor. Receiving error "Pointer freed.

Posted 14 October 2013 - 08:47 PM

Look at line 69 of your test driver. You didn't define an assignment operator. However, because you are trying to use one, the compiler generated an assignment operator for you that does a shallow copy.

That means that copy is now an alias for test because you are referring to the data with pointers. copy is then deleted when it goes out of scope, taking the data for it and, because it's just a shallow copy of test, taking the data for test with it as well. This leaves test in a corrupt state. When the destructor for test is called, it's trying to delete objects that have already been deleted.

Simple fix, define an assignment operator that performs a deep copy.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1