双链表中的智能指针
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双链表中的智能指针相关的知识,希望对你有一定的参考价值。
我正在尝试在双向链表(大学任务)中实现智能指针。在此之前,我使用原始指针在纯C中完成了相同的任务。问题是当我通过addNode()添加新的节点到列表时,我崩溃了两次(我使用CodeLite(g ++),Windows 10 64位)。我假设问题是我的内存管理(Node和List的析构函数)。但我觉得我没有足够的资格来解决这个问题。所以任何帮助将不胜感激。
#include <stdlib.h>
#include <iostream>
#include <memory>
using namespace std;
template <typename T>
struct Node {
T Value;
weak_ptr<Node<T>> prev;
shared_ptr<Node<T>> next;
~Node() {
while (next){
prev = next->next;
next.reset();
next = prev.lock();
}
}
};
template<typename T>
class List
{public:
shared_ptr<Node<T>> start;
weak_ptr<Node<T>> end;
int size;
public:
List(): size(0){};
~List();
void addNode (T value);
};
template <typename T> List<T>::~List()
{
cout<<"List destructor"<<endl;
while (start){
auto sp = end.lock();
end = start->next;
start.reset(sp.get());
}
}
template <typename T> void List<T>::addNode(T value){
Node<T>* nd = new Node<T>;
if (size==0){
start.reset(nd);
start->Value = value;
end = start;
}
else{
auto sp = end.lock();
auto sp2 = end.lock();
sp->next.reset(nd);
sp.reset(sp->next.get());
sp->prev = sp2;
sp->Value = value;
cout<<"Value size is "<<size<<" "<<sp->Value<<endl;
end = sp;
}
size++;
return;
}
int main ()
{
system("CLS");
string a;
string b;
string c;
a = "1 test";
b = "2 test";
c = "3 test";
List<string> ls;
ls.addNode(a);
ls.addNode(b);
ls.addNode(c);
return 0;
}
答案
使用智能指针的关键是自动内存管理,因此你的List
和Node
析构函数不仅执行不当而且冗余。只需删除它们(或将它们清空)。您唯一的任务可能是正确实施addNode()
:
template <typename T> void List<T>::addNode(T value){
auto nd = std::make_shared<Node<T>>();
nd->Value = value; // this should be done in Node constructor
if (size++ == 0){
start = nd;
} else{
auto sp = end.lock();
nd->prev = sp;
sp->next = nd;
}
end = nd;
}
当你处理智能指针时,你通常不会调用reset()
和get()
方法,只有当你需要处理原始指针时出于各种原因(这不是这里的情况)。
注意:正如注释中所述虽然空的析构函数可以正常工作,但由于递归调用可能会出现长列表问题所以您可能只想实现List
析构函数来避免这种情况。再次这应该在不使用reset()
和get()
的情况下完成,通常只使用智能指针:
~List()
{
while( start )
start = start->next;
}
以上是关于双链表中的智能指针的主要内容,如果未能解决你的问题,请参考以下文章