Solution

The compilation error is t.getData(), it should be t->getData() instead. The run-time error is caused by the fact that the many statements t = next; simply re-assign the constant value of next to t at every iteration of the while loops. Since next is only isFinal() when the list has 2 elements, the code works for lists of 1 and 2 nodes, but fails to terminate for lists of more than 2 nodes. This error can be corrected by simply replacing t = next; with t = t->getNext(); throughout the code. The memory leak is caused by the erase() method, which does not deallocate the node itself before terminating. This can by fixed by adding the lines
    next = NULL;
    delete this;
at the end of the erase() method. The same goes for the replaceWith() method which, although is not used in main(), would nonetheless cause another memory leak. The corrected code is as follows:
// [form and print a list of integers]
#include <iostream>

class Node {
public:
  // constructors / destructor
  Node() : next(NULL), previous(NULL) { }
  Node(int a) : next(NULL), previous(NULL), data(a) { }
  ~Node() {
    if (next) {
      delete next;
    }
  }

  // set/get interface
  void setData(int a) {
    data = a;
  }
  int getData(void) {
    return data;
  }
  void setNext(Node* theNext) {
    next = theNext;
  }
  Node* getNext(void) {
    return next;
  }
  void setPrevious(Node* thePrevious) {
    previous = thePrevious;
  }
  Node* getPrevious(void) {
    return previous;
  }

  // list capabilities

  // return true if node is the first of the list, false otherwise
  bool isFirst(void) {
    return !previous;
  }

  // return true if node is the last of the list, false otherwise
  bool isLast(void) {
    return !next;
  }

  // return the size of the sublist starting from this node
  int size(void) {
    Node* t = this;
    int ret = 0;
    while(!t->isLast()) {
      t = t->getNext();
      ret++;
    }
    return ret;
  }

  // append a new given node at the end of the list
  void append(Node* theNext) {
    Node* t = this;
    while(!t->isLast()) {
      t = t->getNext();
    }
    t->setNext(theNext);
    theNext->setPrevious(t);
  }

  // create a new node with value 'a' and append it at the end of the list
  void appendNew(int a) {
    Node* t = this;
    while(!t->isLast()) {
      t = t->getNext();
    }
    Node* theNewNode = new Node(a);
    t->setNext(theNewNode);
    theNewNode->setPrevious(t);
  }

  // remove this node from the list
  void erase(void) {
    previous->setNext(next);
    next->setPrevious(previous);
    next = NULL;
    delete this;
  }

  // replace this node with a given node
  void replaceWith(Node* replacement) {
    previous->setNext(replacement);
    next->setPrevious(replacement);
    next = NULL;
    delete this;
  }

  // find first node with a specified value in sublist starting from this node
  // return NULL if not found
  Node* find(int needle) {
    if (data == needle) {
      return this;
    }
    Node* t = this;
    while(!t->isLast()) {
      t = t->getNext();
      if (t->getData() == needle) {
        return t;
      }
    }
    return NULL;
  }

  // print the data in the sublist starting from this node
  void print(void) {
    Node* t = this;
    while(!t->isLast()) {
      std::cout << t->getData() << ", ";
      t = t->getNext();
    }
    std::cout << t->getData() << std::endl;
  }

protected:
  // pointer to next node in list
  Node* next;

  // pointer to previous node in list
  Node* previous;

private:
  // the integer data stored in the node
  int data;
};

int main(int argc, char** argv) {
  using namespace std;
  int c = 1;
  // create a new list
  Node start(c);
  // add 10 nodes to the list
  while(c < 10) {
    c++;
    start.appendNew(c);
  }
  // print the list
  start.print();  
  // find the node with value 5
  Node* t = start.find(5);
  // erase this node
  t->erase();
  // print the list again
  start.print();

  return 0;
}



Leo Liberti 2008-01-12