我正在为我的c++类编写一个程序,它基本上是一个小型书店应用程序。书店将有一个成员链接列表(ListMemberType)和一个图书链接列表(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
时,我出现了seg错误。我在代码的其他几个地方也遇到了同样的问题,我不知道为什么我在这里出现seg错误,也不知道潜在的问题是什么。(注意:BookType类不包含任何需要重载赋值运算符或复制构造函数的动态数据)
如果有任何帮助,我将不胜感激。我觉得我只是错过了一些我不知道的重要事情。
在GetBook
例程中,考虑dataPtr
已经为NULL的情况
您将访问return tempPtr->component;
//导致segfault。
当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!
如果while
语句中的条件在第一次求值时为false,则tempPtr
将永远不会设置为除NULL
之外的任何值,并且return语句中的tempPtr->component
尝试取消引用空指针并崩溃。
考虑一下,如果while
条件第一次为false,那么函数返回的合理默认值是什么,然后如果tempPtr
在return语句之前为NULL
,则返回该默认值。