我会提前为您寻求帮助而道歉并道歉。我真的不配任何方式。我也为我所知道的是我的草率代码道歉。我不想成为那个的家伙,但我真的很难过我该做什么。
到目前为止,这是故事:
Node::Node()
{
next = nullptr;
book = nullptr;
}
Node::Node(Book* newBook)
{
next = nullptr;
book = newBook;
}
Node::~Node()
{
if (next != nullptr)
{
delete book;
}
}
Node* Node::getNextNode() const
{
return next;
}
void Node::setNext(Node* newNext)
{
if (newNext == nullptr)
{
next = nullptr;
}
else
{
next = newNext;
}
}
Book* Node::getBook() const
{
return book;
}
List::List()
{
first = nullptr;
last = nullptr;
numNodes = 0;
}
List::~List()
{
Node* tempNode = first;
first = first->getNextNode();
while (first != nullptr)
{
delete tempNode;
numNodes--;
tempNode = first;
first = first->getNextNode();
}
last = nullptr;
}
void List::push_front(Node* newNode)
{
Node* tempNode = first;
newNode->setNext(tempNode);
first = newNode;
if (last == nullptr)
{
last = first;
}
numNodes++;
}
void List::push_back(Node* newNode)
{
Node* tempNode = last;
tempNode->setNext(newNode);
last = newNode;
if (first == nullptr)
{
first = last;
}
numNodes++;
}
Node* List::pop_front()
{
if (first != nullptr)
{
Node* tempNode = first;
if (tempNode->getNextNode() == nullptr)
{
numNodes--;
return first;
}
if (first == last)
{
numNodes--;
first = nullptr;
return first;
}
first = first->getNextNode();
numNodes--;
return tempNode;
}
return nullptr;
}
Node* List::pop_back()
{
if (last != nullptr)
{
Node* tempNode = first;
if (first == last)
{
numNodes--;
first = nullptr;
return first;
}
if (tempNode->getNextNode() == nullptr)
{
numNodes--;
return first;
}
while (tempNode->getNextNode()->getNextNode() != nullptr)
{
tempNode = tempNode->getNextNode();
}
last = tempNode;
last->next = nullptr;
numNodes--;
return tempNode;
}
return nullptr;
}
Node* List::getFirst() const
{
return first;
}
Node* List::getLast() const
{
return last;
}
int main()
{
// set up cout for displaying prices
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
// create a List object
List partsList;
cout << "\nPart I: multiple node test: push_front and pop_front\n";
cout << "\n----------------------------------\n";
// build a List using push_front
partsList.push_front(new Node(new Book("Fun With C++", "I. M. Codemann", 95.00)));
partsList.push_front(new Node(new Book("Lousy Linked Lists", "B. A. Hacker", 74.90)));
partsList.push_front(new Node(new Book("Programming Nuts", "R. U. Krazy", 85.25)));
partsList.push_front(new Node(new Book("Silly Syntax", "Irma Coder", 30.15)));
cout << "\nThe original nodes in the List:\n";
printList(partsList);
cout << "\n----------------------------------\n";
// test push_front function
cout << "\nAdding to the front of the List:\n";
cout << "\n----------------------------------\n";
partsList.push_front(new Node(new Book("Python's a Snake", "C. Rules", 65.45)));
partsList.push_front(new Node(new Book("Programming Fables", "J. Aesop", 73.15)));
printList(partsList);
cout << "\n----------------------------------\n";
// test pop-front
cout << "\nRemoving the first node from the list.\n";
cout << "\n----------------------------------\n";
Node* item = partsList.pop_front();
printList(partsList);
if (item != NULL)
delete item;
cout << "\n----------------------------------\n";
cout << "\nPart Two: Push_back and pop_back";
// test push_back
partsList.push_back(new Node(new Book("Coding Shortcuts", "B. Lazy", 110.25)));
partsList.push_back(new Node(new Book("Famous Programmers I Know", "M. T. Set", 126.00)));
cout << "\nAdding two nodes at the end\n";
cout << "\n----------------------------------\n";
printList(partsList);
// test pop-back
cout << "\n----------------------------------\n";
cout << "\nRemove last node from the list\n";
cout << "\n----------------------------------\n";
item = partsList.pop_back();
printList(partsList);
if (item != NULL)
delete item;
// delete all of the Nodes in the list
cout << "\nEmpty the list and delete all nodes\n";
while (partsList.getFirst() != nullptr)
{
Node * t = partsList.pop_front();
delete t;
}
printList(partsList);
// Test Push_front and pop_back - do they handle special case
cout << "\nTesting special case handling for push_front and pop_back\n";
partsList.push_front(new Node(new Book("Test Book 1", "nobody", 1.25)));
Node* t = partsList.pop_back();
cout << "\nThe Node just removed contains " << t->getBook()->getTitle() << endl;
delete t;
// Test push_back and pop_front - do they handle special cases
cout << "\nTesting special case handling for push_back and pop_front\n";
partsList.push_back(new Node(new Book("Test Book 2", "nobody", 1.25)));
t = partsList.pop_front();
cout << "\nThe Node just removed contains " << t->getBook()->getTitle() << endl;
delete t;
// Is the list now empty
cout << "\nThe list should now be empty...\n";
printList(partsList);
cout << "\n-------------------------------------------\n";
cout << "\nEnd of Test";
cout << "\n-------------------------------------------\n";
system("PAUSE");
return 0;
}
void printList(const List& theList)
{
if (theList.getFirst() == nullptr) // if the list is empty
cout << "\nempty list\n";
else
{
Node* t = theList.getFirst();
while (t != NULL)
{
Book* bp = t->getBook();
cout << bp->getTitle() << ' ';
cout << bp->getAuthor() << ' ';
cout << "$" << bp->getPrice() << endl;
t = t->getNextNode();
}
}
}
void printFirstNode(List theList)
{
Node* t = theList.getFirst();
Book* bp = t->getBook();
cout << bp->getTitle() << ' ';
cout << bp->getAuthor() << ' ';
cout << "$" << bp->getPrice() << endl;
t = t->getNextNode();
}
好吧,到目前为止,我到目前为止链接列表的内容似乎相对顺利。该程序仅在homestretch(最后一个printList函数调用)处抛出异常(Proj_02.exe中的0x00E5654B处的未处理异常:0xC0000005:访问冲突读取位置0xDDDDDF1。)。我不确定为什么抛出这个异常,列表应该是完全空的。所以,我必须羞愧地低下头。我该怎么做才能解决这个问题?
谢谢。从内心深处。
答案 0 :(得分:1)
Thomasz&#39;答案是对的,只是一些额外的提示:
无论您将第一个或最后一个设置为nullptr,也可以为另一个设置:
first = last = nullptr;
push_back
无法工作,如果列表为空,则最后是nullptr本身。试试这个:
if(!last)
{
first = last = newNode;
}
else
{
last->setNext(newNode);
last = newNode;
}
++numNodes;
Node类应该是列表类的内部细节,否则你允许在外部修改列表,而List不知道它!使Node成为一个内部类,并更改List的公共接口,使其在以前有Node *的任何地方处理Book *。然后创建和删除List函数中的节点 - 并且不要从Node的析构函数中删除Book。但是,您仍然可以使用Node类来迭代List,因此它将对应于:: std :: list&#39;迭代器。
你可以直接分配newNext:即使它是一个空指针,next
仍然会被正确分配,所以检查只是多余的:
void Node::setNext(Node* newNext)
{
// if (newNext == nullptr)
//{
// next = nullptr;
//}
//else
//{
next = newNext;
//}
}
我可以假设你写了学习清单吗?否则,您可能已经使用了STL中的:: std :: list ...
我允许自己重写列表类,以便进行比较。希望这有助于你...
class List
{
public:
List();
~List();
class Node
{
public:
Node const* getNext() const
{
return next;
}
Book* getBook() const
{
return book;
}
private:
friend class List;
Node(Book*);
Node* next;
Book* book;
};
void push_front(Book* book);
void push_back(Book* book);
Book* pop_front();
Book* pop_back();
Book* getFirst() const;
Book* getLast() const;
Node const* getFirstNode() const
{
return first;
}
private:
Node* first;
Node* last;
unsigned int numNodes;
};
List::Node::Node(Book* newBook)
: next(nullptr), book(newBook)
{
}
List::List()
: first(nullptr), last(nullptr), numNodes(0)
{
}
List::~List()
{
while (first)
{
Node* tempNode = first;
first = first->next;
delete tempNode;
}
}
void List::push_front(Book* book)
{
Node* node = new Node(book);
if (first)
{
node->next = first;
first = node;
}
else
{
first = last = node;
}
++numNodes;
}
void List::push_back(Book* book)
{
Node* node = new Node(book);
if (last)
{
last->next = node;
last = node;
}
else
{
first = last = node;
}
++numNodes;
}
Book* List::pop_front()
{
Book* book = nullptr;
if (first)
{
book = first->book;
Node* tempNode = first;
first = first->next;
if (!first)
{
last = nullptr;
}
delete tempNode;
--numNodes;
}
return book;
}
Book* List::pop_back()
{
Book* book = nullptr;
if (last)
{
book = last->book;
Node* tempNode = first;
if (first == last)
{
first = last = nullptr;
}
else
{
while(tempNode->next != last)
{
tempNode = tempNode->next;
}
delete last;
last = tempNode;
last->next = 0;
}
--numNodes;
}
return book;
}
Book* List::getFirst() const
{
return first ? first->book : nullptr;
}
Book* List::getLast() const
{
return last ? last->book : nullptr;
}
答案 1 :(得分:0)
您的崩溃似乎与此部分代码有关:
Node* List::pop_front()
{
if (first != nullptr)
{
Node* tempNode = first;
if (tempNode->getNextNode() == nullptr)
{
numNodes--;
return first;
}
if (first == last)
{
numNodes--;
first = nullptr;
return first;
}
first = first->getNextNode();
numNodes--;
return tempNode;
}
return nullptr;
}
两种情况:
if (tempNode->getNextNode() == nullptr)
{
numNodes--;
return first;
}
if (first == last)
{
numNodes--;
first = nullptr;
return first;
}
似乎是为了单个元素列表(first == last
和next == nullptr
)的目的。所以,第一个应该是:
if (tempNode->getNextNode() == nullptr)
{
numNodes--;
first = nullptr;
return tempNode;
}
此外:
Node::Node(Book* newBook)
{
next = nullptr;
book = newBook;
}
Node::~Node()
{
if (next != nullptr)
{
delete book;
}
}
在调用时是100%泄漏,如:
new Node(new Book("Test Book 1", "nobody", 1.25))
因为next
仍然是nullptr
,而book
应归Node
所有,但不是{0}}。此外,最后一个元素将始终泄漏。