Pamela Price
Pamela Price

Reputation: 41

Using Linked List as an object in a class in C++

I am trying to implement a "facebook" like problem.

I have created a class called User. A user has a list of friends.

I tried this using a C++ vector and it worked without any problems.

Then I tried changing the vector to a LinkedList, using a template class I have.

The template has a copy constructor and destructor.

I have tested and debugged the template for other datatypes.

class User
{
private:
    string uname;
    //vector<User> myfriends;
    LinkedList<User> myfriends;

public:
    User() { uname = "none"; }
    User(string n) { uname = n; }
    string getName() { return uname; }
    void addFriend(User &u) 
    { 
        //add u to me
        myfriends.appendNode(u);

        //add "me" to u
        u.myfriends.appendNode(*this); //causes problem?

        //myfriends.push_back(u);  //when using vector
        //u.myfriends.push_back(*this); //works when using vector

    }
    void listFriends()
    {
        cout << uname << " has " << myfriends.getSize() << " friends" << endl;
        myfriends.displayList();  //prints values in linked list
    }

    friend ostream& operator<< (ostream& out, User u)
    {
        out << u.uname;
        return out;
    }

};

I want the addFriend function to make a "mutual" connection.

This works when I use a vector, but when using this LinkedList and this testing program:

User u1("joe");
User u2("sam");

u1.addFriend(u2);
u1.listFriends();

I get the correct output

joe has 1 friends
sam

However I also get a runtime error which tells me something funky is happening with my pointers.

"A problem caused the program to stop working correctly."

I am using Visual Studio Express 2017.

I am trying to figure out if there is some basic flaw with making the connections this way, trying to draw some pictures to work it out.

Any thoughts on what might be causing the runtime error?

Here's the displayList() function:

template <class T> 
void LinkedList<T>::displayList() 
{ 
    //"walk" the list and print each value 
    ListNode *nodePtr; 
    //to walk the list
    //start at the beginning 
    nodePtr = head; 
    //while there is a node to print 
    while (nodePtr) { 
        //display the value 
        cout << nodePtr->data << endl; 
        //move to next node 
        nodePtr = nodePtr->next; 
    } 
} 

Here is displayList code in LinkedList template

template <class T>
void LinkedList<T>::displayList()
{
    //"walk" the list and print each value
    ListNode *nodePtr;  //to walk the list
                        //start at the beginning
    nodePtr = head;
    //while there is a node to print
    while (nodePtr)
    {
        //display the value
        cout << nodePtr->data << endl;
        //move to next node
        nodePtr = nodePtr->next;
    }
}

Here is appendNode

template <class T>
void LinkedList<T>::appendNode(T value)
{
    ListNode *newNode;  //to point to a new node
    ListNode *nodePtr;  //to move through the list

                        //allicate a new node and store value
    newNode = new ListNode;
    newNode->data = value;
    newNode->next = nullptr;

    //if list is empty make this the first node
    if (!head)
        head = newNode;
    else // insert at end of list
    {
        //initialize nodePtr to head of list
        nodePtr = head;
        //"walk" the listt to find the last node
        while (nodePtr->next)  //if not null this is true
        {
            nodePtr = nodePtr->next;
        }
        //nodePtr now points to last node in list
        //add the new node
        nodePtr->next = newNode;
        //remember it's next has already been assigned to null
    }
    numElements++;

}

Here is link https://repl.it/@prprice16/GrowlingFastRule

Upvotes: 2

Views: 128

Answers (1)

Jay Wai Tan
Jay Wai Tan

Reputation: 179

You have

LinkedList<User> myfriends;

When you do

void addFriend(User &u) 
{ 
    //...
}

You will do a full copy of User, including the LinkedList object in it. However, inside your LinkedList, you did not specify an assignment operator, meaning your head for the User passed in will be directly assigned, leaving you with 2 LinkedList with the same head.

Hence the same head pointer will be freed twice.

Upvotes: 1

Related Questions