Problems with my custom linked list class

Started by
14 comments, last by ISDCaptain01 11 years, 4 months ago
Okay the problem occurs in my implementation file. I first declare a list, add some numbers to it, then I declare an iterator and try to point it towards the list but no luck.

[source lang="cpp"]#include <iostream>
#include "SingleListNode.h"
#include "SingleLinkedList.h"
#include "SingleListIterator.h"
using namespace std;


int main()
{

// create a new linked list.
SLinkedList<int> list;

// insert 10, 20 and 30.
list.Append( 10 );
list.Append( 20 );
list.Append( 30 );

cout << "the list contains: ";

// create a new iterator, and make it point to the
// beginning of the list.
SListIterator<int> itr(list);


// loop through the list while the iterator is valid.
for( itr.Start(); itr.Valid(); itr.Forth() )
{
cout << itr.Item() << ", ";
}

// reset the iterator to the beginning again.
itr.Start();

cin.get();
return 0;

}[/source]

I keep on getting this error:

\desktop\singly linked list\singly linked list\example.cpp(23): error C2664: 'SListIterator<Datatype>::SListIterator(SLinkedList<Datatype> *,SListNode<Datatype> *)' : cannot convert parameter 1 from 'SLinkedList<Datatype>' to 'SLinkedList<Datatype> *'
1> with
1> [
1> Datatype=int
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
Advertisement
here are the other files:
[source lang="cpp"]#include "SingleLinkedList.h"
#include "SingleListNode.h"
using namespace std;

template <class Datatype>


class SListIterator
{
public:


//Constructor
SListIterator(SLinkedList<Datatype> *p_list = 0, SListNode<Datatype> *p_node = 0)
{
m_list = p_list;
m_node = p_node;
}


//Start: Resets the iterator to point to the first node in the list
void Start()
{
if(m_list != 0)
{
m_node = m_list->m_head;
}
}


//Forth: Moves the iterator to the next node in the list
void Forth()
{
if(m_node != 0)
{
m_node = m_node->m_next;
}
}


//Item: Returns a reference to the item stored in the node
//that the iterator is pointing to
Datatype& Item()
{
return m_node->m_data;
}


//Valid: Check to see if the iterator is pointing to a non-0 node
bool Valid()
{
if(m_node != 0)
return true;
else
return false;
}


//GetIterator: Creates a new iterator pointing to the head of the list
SListIterator<Datatype> GetIterator()
{
return SListIterator<Datatype>(this, m_head);
}



//Class Variables
SListNode<Datatype> *m_node;
SLinkedList<Datatype> *m_list;



};


[/source]

[source lang="cpp"]

#include <iostream>
#include "SingleListNode.h"
using namespace std;

template <class Datatype>


class SLinkedList
{
public:


//Constructor
SLinkedList()
{
m_head = 0;
m_tail = 0;
m_count = 0;
}

//Destructor
~SLinkedList()
{
//temporary node pointers
SListNode<Datatype> *itr = m_head;
SListNode<Datatype> *next;
while(itr != 0)
{
//Save the pointer to the next node
next->m_head->m_next;

//Delete the current node
delete itr;

//Make the next node the current node
itr = next;
}
}


//Append: Adds a new node to the end of the list
void Append(Datatype p_data)
{
if(m_head == 0)
{
//Create a new head node
m_head = m_tail = new SListNode<Datatype>;
m_head->m_data = p_data;
}
else
{
//Insert a new node after the tail
m_tail->InsertAfter(p_data);

//Update the tail
m_tail = m_tail->m_next;
}

//Keep track of the number of nodes
m_count++;
}


//Prepend: Adds a new node to the beginning of the list
void Prepend(Datatype p_data)
{
//Creata a new node
SListNode<Datatype> *newnode = new SListNode<Datatype>;
newnode->m_data = p_data;
newnode->m_next = m_head;

//Set the head node and the tail node if needed
m_head = newnode;
if(m_tail == 0)
{
m_tail = m_head;
}
m_count++;
}


//RemoveHead: Removes the beginning node in the list
void RemoveHead()
{
SListNode<Datatype> *node = 0;
if(m_head != 0)
{
//Make node point to the next node
node = m_head->m_next;

//then delete the head and make the pointer
//point to node
delete m_head;
m_head = node;

//if the head is null, then you've just deleted the only node
//in the list. Set the tail to 0
if(m_head == 0)
{
m_tail = 0;
}
m_count--;
}
}


//RemoveTail: Removes the ending node of the tail
void RemoveTail()
{
SListNode<Datatype> *node = m_head;
//If the list isn't empty, then remove a node
if(m_head != 0)
{
//If the head is equal to the tail, then
//the list has 1 node, and you are removing it
if(m_head == m_tail)
{
//Delete the node and set both pointers
//to 0
delete m_head;
m_head = m_tail = 0;
}
else
{
//Skip ahead until you find the node
//right before the tail node
while(node->m_next != m_tail)
{
node = node->m_next;
}
//Make the tail point to the before the
//current tail and delete the old tail
m_tail = node;
delete node->m_next;
node->m_next = 0;
}
m_count--;
}
}



//Class Variables
SListNode<Datatype> *m_head;
SListNode<Datatype> *m_tail;
int m_count;

};[/source]
[source lang="cpp"]#pragma once

#include <iostream>
using namespace std;

template <class Datatype>


class SListNode
{
public:

//Holds data that will be stored in the node
Datatype m_data;

//Pointer to another SListNode class
SListNode<Datatype> *m_next;


void InsertAfter(Datatype p_data)
{
//Create the new node
SListNode<Datatype> *newnode = new SListNode<Datatype>;
newnode->m_data = p_data;

//Make the new node point to the next node
newnode->m_next = m_next;

//Make the previous node point to the new node
m_next = newnode;
}

};[/source]
It's telling you what the problem is: your iterator constructor wants a pointer but you're passing the list by value. You can use &list to get a pointer to the list object.
Also, the second arg for the ctor is type SListNode<Datatype>*, but the type being passed is SLinkedList<int>.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
K i fixed that but now im getting this error:

c:\users\aasim\desktop\singly linked list\singly linked list\singlelinkedlist.h(32): error C2039: 'm_head' : is not a member of 'SListNode<Datatype>'
1> with
1> [
1> Datatype=int
1> ]
1> c:\users\aasim\desktop\singly linked list\singly linked list\singlelinkedlist.h(25) : while compiling class template member function 'SLinkedList<Datatype>::~SLinkedList(void)'
1> with
1> [
1> Datatype=int
1> ]
1> c:\users\aasim\desktop\singly linked list\singly linked list\example.cpp(15) : see reference to class template instantiation 'SLinkedList<Datatype>' being compiled
1> with
1> [
1> Datatype=int
1> ]
1>c:\users\aasim\desktop\singly linked list\singly linked list\singlelinkedlist.h(32): error C2227: left of '->m_next' must point to class/struct/union/generic type
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
singlelinkedlist.h - line 32: 'm_head' : is not a member of 'SListNode<Datatype>'

That's about as plain as it gets.

Read what the thing is saying. It's not lying to you.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
As SiCrane pointed out, the compiler is telling you:

  • What the problem is
  • The file the problem is in
  • The exact line of the problem

The topmost error:
c:\users\aasim\desktop\singly linked list\singly linked list\[color=#ff0000]singlelinkedlist.h (FILE) [color=#0000ff](32 (LINE NUMBER)): error C2039: [color=#800080]'m_head' : [color=#ff8c00]is not a member of '[color=#800080]SListNode<Datatype>'

When I look at your posted file, "singlelinkedlist.h", and look at line 32, I see a 'SListNode<>' trying to access a member-variable 'm_head', even though SListNode<> classes don't have a m_head variable.

You have:
next->m_head->m_next; //Problem! 'next' doesn't have any member called 'm_head'
When you really want:
itr = next->m_next;
Okay thanks for the help, sorry about asking such question, but I just get frustrated sometimes lol. Especially what I typed into my compiler is straight from the book(I double checked).

After looking at your feedback i tried to come up with a similar solution by disecting the the destructor

okay so I want my iterator to point to the head or front of the list, fair enough:
SListNode<Datatype> *itr = m_head;

okay next I wanna create another node pointer that will point the node right after iterator:
SListNode<Datatype> *next;

then I start a while loop when iterator is pointing to something
while(itr != 0)
{

then i want the next node pointer to do its job
next = itr->m_next;

rest of the code is the same


but now it builds successfully but crashes at this line in example.cpp
cout << itr.Item() << ", ";


I just feel so lost since its my first time dealing with linkedlist
I dunno if wrapping LL in a class is the best first exercise. You really have to be very comfortable with pointers before you can sling around LL code easily, and they're still error prone.

That being said, the first 2 problems you've mentioned had to do with type awareness, not linked lists.

A linked list (you've probably heard this) is easier to visualize if you draw a picture of a train with a head, a tail and boxcars in-between. If you do this on paper and then draw a new picture for each step in the process it becomes much easier to see what order things need to be done in. (It doesn't have to be a train, just some labelled boxes with arrows between them works too.)

Anyway, don't stress out about this. Take a break or a nap or something and just let it simmer in your subconscious. It really does take time for the brain to adjust to this kind of concept. Eventually it just clicks and you're fine.

As for your most recent error - fire up that debugger. Put a breakpoint at the start of the loop and start walking through it step-by-step until you see a value go bad.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Two stylistic suggestions: (note: These aren't bugs, and aren't related to your problem)

  • Don't compare to 0, compare to NULL (or if using C++11, compare to nullptr). It describes your intent better.
  • Don't compare at all! if(pointer != 0) can be simplified as if(pointer), and if(pointer == 0) can be simplified as if(!pointer).


About your current crash:
I don't see where the problem is, so now we need to move to the debuffer (as Khatharr mentioned). Using a debugger, first put a breakpoint on the line that crashes in the for-loop, and 'continue' through it multiple loops. Does it crash on the first loop? The second? The last? Are you going past the end?
This is the first bit of information you are looking for; oddities that might give you a hint where the problem is really occurring.
If you still can't find the cause, then you might want to "step into" the crashing function, and observe the current values of the variables right before the program crashes.

Using those two together (observation of program 'flow' before the crash, and observation of program 'state' before the crash), you can usually find the cause within a few minutes (it'll take longer if you are just learning how to use your debugger). Unless it's an invalid pointer writing over the wrong memory somewhere - the bane of programmers. sad.png

I'm not familiar with how Visual Studio's debugger works (I assume you're using Visual Studio), so I can't help you with precise detail on that.

This topic is closed to new replies.

Advertisement