Reputation: 540
I'm trying to implement a simple doubly linked list with exposed nodes in C++ like this (some methods omitted, should be pretty clear as to what they do):
template<typename T>
class Node
{
public:
Node(T _value)
{
m_Data = _value;
m_HasParent = false;
m_HasNext = false;
m_Parent = NULL;
m_Next = NULL;
}
void insertAfter(Node<T>* _item)
{
m_Next = _item;
m_HasNext = true;
_item->insertBefore(this);
}
void insertBefore(Node<T>* _item)
{
if(m_HasParent)
{
m_Parent->insertAfter(_item);
_item->insertAfter(this);
}
else
{
m_Parent = _item;
m_HasParent = true;
}
}
private:
T m_Data;
Node<T>* m_Parent;
Node<T>* m_Next;
bool m_HasParent;
bool m_HasNext;
};
template<typename T>
class LinkedList
{
public:
LinkedList()
{
m_Root = NULL;
m_HasRoot = false;
}
~LinkedList()
{
if(m_HasRoot)
{
delete m_Root;
}
}
void pushFront(T _value)
{
if(m_HasRoot)
{
Node<T>* node = new Node<T>(_value);
m_Root->insertBefore(node);
node->insertAfter(m_Root);
m_Root = node;
}
else
{
m_Root = new Node<T>(_value);
m_HasRoot = true;
}
}
void pushBack(T _value)
{
if(m_HasRoot)
{
Node<T>* last = m_Root;
while(true)
{
if(last->getHasNext())
{
last = last->getNext();
}
else
{
break;
}
}
Node<T>* node = new Node<T>(_value);
last->insertAfter(node);
return;
}
else
{
m_Root = new Node<T>(_value);
m_HasRoot = true;
}
}
T operator[](int _i)
{
Node<T>* last = m_Root;
for(int i = 0; i <= _i; i++)
{
if(last->getHasNext())
{
last = last->getNext();
}
else
{
break;
}
}
return last->getData();
}
private:
Node<T>* m_Root;
bool m_HasRoot;
};
However, when executing the following little test:
int main(int argc, char** argv)
{
LinkedList<int> l;
l.pushBack(0);
l.pushBack(1);
l.pushBack(2);
l.pushBack(3);
int count = l.getCount();
std::cout << "count: " << count << std::endl;
for(int i = 0; i < count; i++)
{
std::cout << "Value at [" << i << "]: " << l[i] << std::endl;
}
std::string s;
std::cin >> s;
return 0;
}
I expect to see the numbers 0, 1, 2, 3
printed out in this order, but this is what I get:
For some reason, the insertion to the back doesn't quite work. I find nothing fundamentally wrong with my code, can anybody spot the problem? This is on MinGW 5.1, 64bit, Windows 10 64bit. However, when executing this problem on runnable.com, everything seems to work just fine?? See this draft. Is this a bug in MinGW or some mistake on my part?
Now this is weird, sometimes it seems to work in runnable, and sometimes it yields the same result as on my local machine... I'm thoroughly confused.
Upvotes: 0
Views: 51
Reputation: 19607
Try changing the loop condition inside ListWidget::operator[]
from i <= _i
to i < _i
. There should be no iteration for _i
equal 0
.
The sign is that you're starting printing from the second element i.e. 1
and printing the last element twice. You forgot about the root node.
Note that you're checking if a node has a succesor, but you aren't checking if the list is not empty (m_root != nullptr
). Make this consistent - either remove all possible cases of UB or don't check anything.
Upvotes: 3