[英]Back Traversal issue in linked list
以下是 C++ 編寫的帶有 Node 類和 main 函數的鏈表。 列表正在使用“next()”函數向前遍歷,但是當使用“back()”向后遍歷時會產生執行時間錯誤。
#include <iostream>
using namespace std;
class Node {
public:
int object;
Node *nextNode;
Node *prevNode;
public:
int get(){
return object;
}
void set(int object){
this->object = object;
}
Node* getNext(){
return nextNode;
}
void setNext(Node *nextNode){
this->nextNode = nextNode;
}
Node* getPrev(){
return prevNode;
}
void setPrev(Node *prevNode){
this->prevNode = prevNode;
}
};
class List {
public:
Node* headNode;
Node* currentNode;
int size;
public:
List(){
headNode = new Node();
headNode->setNext(NULL);
headNode->setPrev(NULL);
currentNode = NULL;
int size = 0;
}
void add(int addObject){
Node* newNode = new Node();
newNode->set(addObject);
if(currentNode != NULL){
newNode->setNext(currentNode->getNext());
newNode->setPrev(currentNode);
currentNode->setNext(newNode);
currentNode = newNode;
}
else {
newNode->setNext(NULL);
newNode->setPrev(headNode);
headNode->setNext(newNode);
currentNode = newNode;
}
size++;
}
int get(){
if(currentNode != NULL) {
return currentNode->get();
}
}
bool next(){
if(currentNode == NULL) return false;
currentNode = currentNode->getNext();
if(currentNode == NULL) return false;
else return true;
}
bool back(){
if(currentNode == NULL) return false;
currentNode = currentNode->getPrev();
if(currentNode == NULL) return false;
else return true;
}
void start(){
currentNode = headNode;
}
void remove() {
if (currentNode != NULL && currentNode != headNode){
delete currentNode;
size--;
}
}
int length() {
return size;
}
};
int main(){
List list;
list.add(5);
list.add(13);
list.add(4);
list.add(8);
list.add(48);
list.add(12);
list.start();
while(list.next()){
cout<<endl<<"Element: " << list.get() << endl;
}
cout<<endl<<"BACK"<<endl;
while(list.back()){
cout<<endl<<"Element: " << list.get() << endl;
}
}
Back() 函數應該以相反的方向(從結束到開始)遍歷列表。相反的方式。 有時這段代碼會掛起 CPU,有時它只運行 next() 函數,而對於 back() 函數,它保持沉默而不做任何事情。
首先,讓我們修復代碼:
bool next(){
if(currentNode == nullptr) return false;
// if next is null we are at the end, don't go futher
if ( currentNode->getNext() == nullptr ) return false;
currentNode = currentNode->getNext();
return true;
}
bool back(){
if(currentNode == nullptr) return false;
// if prev is head, we are at the start, stop here
if ( currentNode->getPrev() == headNode) return false;
currentNode = currentNode->getPrev();
return true;
}
邏輯:
// we are at the last element, so we have to print BEFORE going back
do{
cout<<endl<<"Element: " << list.get() << endl;
} while (list.back());
警告:
警告:未使用的變量“大小”
在這種情況下,有這個警告是可以的,如果你想擺脫它,你可以使用方法length()
。
在成員函數“int List::get()”中:警告:控制到達非空函數的結尾 [-Wreturn-type]
在你的get
方法中, if(currentNode == nullptr )
你什么都不返回,它會導致一個錯誤。 解決此問題的一種方法是throw
異常。
int get(){
if(currentNode == nullptr ) {
throw std::logic_error("CurrentNode is null");
}
return currentNode->get();
}
我個人認為最好的解決方案是:對List
所有成員函數進行編碼,使currentNode
不能為 null。
內存管理
你用new
創建你的節點,但你從不使用delete
所以你有內存泄漏。 查看 valgrind(網站網站或這篇不錯的帖子),它非常有幫助。
valgrind ./leaky --leak-check=full
....
==3225== HEAP SUMMARY:
==3225== in use at exit: 168 bytes in 7 blocks
==3225== total heap usage: 9 allocs, 2 frees, 73,896 bytes allocated
==3225==
==3225== LEAK SUMMARY:
==3225== definitely lost: 24 bytes in 1 blocks
==3225== indirectly lost: 144 bytes in 6 blocks
==3225== possibly lost: 0 bytes in 0 blocks
==3225== still reachable: 0 bytes in 0 blocks
==3225== suppressed: 0 bytes in 0 blocks
所以是的,valgrind 發現了一個漏洞。
您需要添加一個析構函數。
~List(){
// first be sure that we are at one end
while (next()) {}
while (back())
{
std::cout << "delete the node we just left : " << currentNode->getNext()->get() << std::endl;
delete currentNode->getNext();
}
// don't forget this one (without valgrind I will have miss it!)
delete currentNode;
std::cout << "finaly we clear the head" << std::endl;
delete headNode;
}
但是現在如果我們寫:
List list2 = list;
我們有 :
double free or corruption (fasttop)
因為我們有 2 個對象試圖刪除相同的內存。
我們可以禁止復制:
List(const List&) = delete;
List& operator=(const List&) = delete;
通常大多數內存管理是通過智能指針完成的。
能見度:
為您的屬性使用private
:
private :
int object;
Node *nextNode;
Node *prevNode;
和
private:
Node* headNode;
Node* currentNode;
size_t size = 0;
最終版本: Demo
用valgrind檢查:
==3532== HEAP SUMMARY:
==3532== in use at exit: 0 bytes in 0 blocks
==3532== total heap usage: 9 allocs, 9 frees, 73,896 bytes allocated
==3532==
==3532== All heap blocks were freed -- no leaks are possible
沒有泄漏,一切都很好;)
希望能幫助到你 !
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.