【发布时间】:2014-02-11 02:37:13
【问题描述】:
我创建了这个链表类以在我的工作中使用它,但我有这个异常“game.exe 中 0x003216D2 的第一次机会异常:0xC0000005:访问冲突写入位置 0x00000004。”它来自擦除功能,有人可以告诉我如何修复它并解释它的问题
#ifndef LINKEDLIST_HPP
#define LINKEDLIST_HPP
#include <vector>
#include <cassert>
template<typename T>
class Linkedlist
{
private:
// The basic doubly linked Linkedlist node.
// Nested inside of Linkedlist, can be public
// because the Node is itself private
struct Node
{
T _data;
Node *_prev;
Node *_next;
Node( const T & d = T(), Node * p = NULL, Node * n = NULL )
: _data( d ), _prev( p ), _next( n ) { }
// Rvalue
Node(Node && n)
{
_data = std::move(n._data);
_prev = std::move(n._prev);
_next = std::move(n._next);
}
// = operator
Node& operator =(Node && n)
{
_data = std::move(n._data);
_prev = std::move(n._prev);
_next = std::move(n._next);
return *this;
}
};
public:
class LinkedListIter : public std::iterator<std::forward_iterator_tag , T , int>
{
Node* _node;
public:
LinkedListIter(Node* p=nullptr) : _node(p){}
~LinkedListIter(){}
Node* getNode(){return _node;}
T operator * () { return _node->_data; }
LinkedListIter & operator ++()
{
_node = _node->_next;
return *this;
}
LinkedListIter operator ++(int)
{
LinkedListIter retVal = *this;
++this;
return retVal;
}
bool operator < (LinkedListIter const& rhs) const
{
return _Node < rhs._Node;
}
bool operator != (LinkedListIter const& rhs) const
{
return _Node != rhs._pNode;
}
bool operator == (LinkedListIter const& rhs) const
{
return _Node == rhs._Node;
}
};
Linkedlist( )
{ init(); }
~Linkedlist()
{
clear();
delete _head;
delete _tail;
}
Linkedlist(const Linkedlist & rhs)
{
init( );
*this = rhs;
}
const Linkedlist & operator= (const Linkedlist & rhs)
{
if( this == &rhs )
return *this;
clear( );
for(const_iterator itr = rhs.begin(); itr != rhs.end( ); ++itr)
push_back(*itr);
return *this;
}
// Return iterator representing beginning of Linkedlist.
// Mutator version is first, then accessor version.
LinkedListIter begin()
{ return LinkedListIter(_head->_next);}
// Return iterator representing endmarker of Linkedlist.
// Mutator version is first, then accessor version.
LinkedListIter end()
{ return LinkedListIter(_tail); }
// Return number of elements currently in the Linkedlist.
int size() const
{ return _size; }
// Return true if the Linkedlist is empty, false otherwise.
bool empty() const
{ return size() == 0; }
void clear()
{
while( !empty() )
pop_front();
}
// front, back, push_front, push_back, pop_front, and pop_back
// are the basic double-ended queue operations.
T & front()
//{ return *begin( ); }
{return _head->_next.data}
const T & front() const
{ return *begin(); }
T & back( )
{ return *--end(); }
const T & back() const
{ return *--end(); }
void push_front(const T & x)
{ insert( begin(), x ); }
void push_back(const T & x)
{ insert( end(), x ); }
void pop_front()
{ erase(begin()); }
void pop_back()
{ erase(--end()); }
// Insert x before itr.
LinkedListIter insert(LinkedListIter& itr, const T & x)
{
Node *p = new Node(x,itr.getNode()->_prev,itr.getNode());
_size++;
return LinkedListIter(p->_prev = p->_prev->_next = new Node(x, p->_prev, p));
}
// Erase item at itr.
LinkedListIter erase(LinkedListIter itr)
{
Node *p = itr.getNode();
LinkedListIter retVal(p->_next);
p->_prev->_next = p->_next;
p->_next->_prev = p->_prev;
delete p;
_size--;
return retVal;
}
LinkedListIter erase(LinkedListIter start, LinkedListIter end)
{
for(iterator itr = start; itr != end;)
itr = erase(itr);
return end;
}
private:
int _size;
Node *_head;
Node *_tail;
void init()
{
_size = 0;
_head = new Node;
_tail = new Node;
_head->_next = _tail;
_tail->_prev = _head;
}
};
#endif
【问题讨论】:
-
除非您正在做需要编写自己的类的作业,否则请使用 std::list。有用!为什么要使用右值引用(&&)?我猜你正在学习 C++,我猜你没有得到右值的细微差别。提示:如果你打得好,编译器会为你编写那些默认的右值函数。
-
您是否使用调试器查看错误在哪一行?
-
编写单元测试来验证它是否按预期工作。对于非常简单的事情,从完全简单的情况开始,例如,
size()在第一次构造时返回零,size()在推送一个项目后返回一个,在推送一个项目后,front()正确返回该项目,等等。在一个做一些事情的小测试用例中调查一个问题要比在将它用于实际任务时挖掘一些大的复杂崩溃要容易得多。随着越来越多的测试通过,添加越来越残酷的新测试。 -
@jeffamaphone 异常发生在行擦除函数行 p->_next->_prev = p->_prev;
-
@user3277743:所以在
p->_next->_prev中,子表达式p->_next为空。你有一个很好的提示,一个节点的_next指针为空。现在检查该节点是如何创建和插入的,以及 null 是否是该指针的有效值。
标签: c++ visual-c++ c++11 data-structures