1

我正在为我的 c++ 类开发一个程序,该程序基本上是一个小型书店应用程序。书店要有Member链表(ListMemberType)和Books链表(ListBookType)。链表的每个节点都由指向下一个组件的链接和一个组件组成。该组件的类型为 BookType。

这是 ListBookType 的头文件

#include "bookType.h"

typedef BookType ItemType;    // Type of each component
struct NodeType;              // Forward declaration

class ListBookType {
public:
    const ListBookType& operator=(const ListBookType& rightObject);
    //overload assignment operator
    //will set the left side equal to right side
    void Replace(ItemType theNewItem, ItemType theOldItem);
    //Pre:These are the same book(ISBN is the same)
    //Post: old component will be replaced with the new component
    ListBookType();
    // Constructor
    // Post: Empty list has been created
    ~ListBookType();
    // Destructor
    // Post: All nodes are returned to the heap
    ListBookType(const ListBookType& otherList);
    // Copy constructor
    // Post:  A deep copy of otherList is created and dataPtr is the
    //        external pointer to this copy

    // Action respnsibilities
    void Insert(ItemType item);
    // Pre:  List is not full and item is not in the list
    // Post: item is in the list and length has been incremented
    void Delete(ItemType item);
    // Post: item is not in the list
    void ResetList();
    // The current position is reset to access the first item in the list
    ItemType GetNextItem();
    // Assumptions:  No transformers are called during the iteration.
    // There is an item to be returned; that is, HasNext is true when
    // this method is invoked
    // Pre:  ResetList has been called if this is not the first iteration
    // Post: Returns item at the current position.

    // Knowledge responsibility
    int GetLength() const;
    // Post: Returns the length of the list
    bool IsEmpty() const;
    // Post: Returns true if list is empty; false otherwise
    bool IsFull() const;
    // Post: Returns true if list if full; false otherwise
    bool IsThere  (ItemType item ) const;
    // Post: Returns true if item is in the list and false otherwise
    bool HasNext() const;
    // Returns true if there is another item to be returned; false
    // otherwise
    ItemType GetBook(ItemType bookToGet)const;
    //Pre: Book is in list
    //Post: the book is returned
    //Pre: Book is in the list
    //Post: Book with matching ISBn will be returned
    private:
    NodeType* dataPtr;     // Pointer to the first node in the list
    int length;
    NodeType* currentPos;   // Pointer to the current position in a traversal
    NodeType* lastPtr;
};

这是我知道的包含我的错误的规范文件部分,以及我认为可能导致错误的部分。

#include "listBookType.h"
#include "bookType.h"
#include <iostream>
#include <cstddef>           // For NULL

using namespace std;

typedef NodeType* NodePtr;
struct NodeType {
   ItemType component;
   NodePtr link;
};

const ListBookType& ListBookType::operator=(const ListBookType& rightObject) {
   cout<<"Assignment operator bookList"<<endl;

   NodePtr fromPtr;    // Pointer into list being copied from
   NodePtr toPtr;      // Pointer into new list being built
   if(this != &rightObject) {
      if (rightObject.dataPtr == NULL) {
         dataPtr = NULL;
         return *this;
      }
      // Copy first node
      fromPtr = rightObject.dataPtr;
      dataPtr = new NodeType;
      dataPtr->component = fromPtr->component;
      // Copy remaining nodes
      toPtr = dataPtr;
      fromPtr = fromPtr->link;
      while (fromPtr != NULL)
      // Copying nodes from original to duplicate
      {
         toPtr->link = new NodeType;        // Store new node in link of last
                                                // node added to new list
         toPtr = toPtr->link;           // toPtr points to new node
         toPtr->component = fromPtr->component; // Copy component to new node
         fromPtr = fromPtr->link;       // fromPtr points to next node
                        // of original list
      }
      toPtr->link = NULL;
      lastPtr = toPtr;      // Set last pointer
   }
   return *this;
}


ItemType ListBookType::GetBook(ItemType bookToGet)const {
   NodePtr currPtr = dataPtr;      // Loop control pointer
   NodePtr tempPtr = NULL;

   while (currPtr != NULL && currPtr->component != bookToGet
       && currPtr->component < bookToGet) {
     tempPtr = currPtr;
     currPtr = currPtr->link;
   }

   cout<<"right before return of getBook"<< endl;

   return tempPtr->component;
}

ListBookType::ListBookType(const ListBookType& otherList) {
   cout<<"copy construct book list"<< endl;
   NodePtr fromPtr;    // Pointer into list being copied from
   NodePtr toPtr;      // Pointer into new list being built

   if (otherList.dataPtr == NULL) {
      dataPtr = NULL;
      return;
   }
   // Copy first node
   fromPtr = otherList.dataPtr;
   dataPtr = new NodeType;
   dataPtr->component = fromPtr->component;
   // Copy remaining nodes
   toPtr = dataPtr;
   fromPtr = fromPtr->link;
   while (fromPtr != NULL) { // Copying nodes from original to duplicate
      toPtr->link = new NodeType;       // Store new node in link of last
                        // node added to new list
      toPtr = toPtr->link;          // toPtr points to new node
      toPtr->component = fromPtr->component; // Copy component to new node
      fromPtr = fromPtr->link;      // fromPtr points to next node
                        // of original list
   }
   toPtr->link = NULL;
   lastPtr = toPtr;     // Set last pointer
}



ListBookType::~ListBookType() {
   cout<< "destructor book list"<< endl;
   NodePtr tempPtr;
   NodePtr currPtr = dataPtr;
   while (currPtr != NULL) {
      tempPtr = currPtr;
      currPtr = currPtr->link;
      delete tempPtr;
   }
}

我遇到的问题在GetBook(ItemType bookToGet). 我追查了问题,当我返回时我出现了段错误tempPtr->component。我在代码的其他几个地方也遇到了同样的问题,我不知道为什么我在这里出现段错误或潜在的问题可能是什么。(注意:BookType 类不包含任何需要重载赋值运算符或复制构造函数的动态数据)

我真的很感激任何帮助。我觉得我只是错过了一些我不知道的重要事情。

4

2 回答 2

2

在您的GetBook例程中考虑dataPtr已经为 NULL 的情况。

您将访问return tempPtr->component;// 导致段错误。

dataPtr您应该单独处理为 NULL的情况。

while (currPtr != NULL && currPtr->component != bookToGet // dataPtr = currPtr is NULL 
       && currPtr->component < bookToGet){
  tempPtr = currPtr;
  currPtr = currPtr->link;
}
cout<<"right before return of getBook"<< endl;
return tempPtr->component; // SEGFAULT!
于 2012-12-01T03:03:32.897 回答
0

如果while语句中的条件在第一次评估时为 false,则tempPtr永远不会设置为 以外的任何值NULL,并且tempPtr->componentreturn 语句中的 尝试取消引用空指针并崩溃。

想想如果while第一次条件为 false 时函数返回的合理默认值是什么,然后如果tempPtrNULL在 return 语句之前,则返回该默认值。

于 2012-12-01T03:03:02.157 回答