aerotwelve
aerotwelve

Reputation: 307

Trying to understand pointers and double pointers

I'm trying to implement a simple linked list in C++. I can create nodes and they seem to link themselves correctly. My question involves the listIterate() function, but I've attached the entire code here in case it is needed.

#include <iostream>
using namespace std;

//Wrapper class which allows for easy list management
class LinkedList {

    //Basic node struct
    struct node {
        int data;
        node *link; 
    }; 

    node *head; //Pointer to the head (also referred to as root) node, or the first node created.
    node *current; //Pointer to the /latest/ node, or the node currently being operated on.
    node *tail; //Pointer to the tail node, or the last node in the list. 

public:

    //Default constructor. Creates an empty list.
    LinkedList() {
        head = NULL;
        current = NULL;
        tail = NULL;
        cout << "*** Linked list created. Head is NULL. ***\n";
    }

    //Default destructor. Use to remove the entire list from memory.
    ~LinkedList() {
        while(head != NULL) {
            node *n = head->link;
            delete head;
            head = n;
        }
    }

    /*
    appendNode() 
    Appends a new node to the end of the linked list. Set the end flag to true to set the last node to      null, ending the list.
    */
    void appendNode(int i) {

        //If there are no nodes in the list, create a new node and point head to this new node.
        if (head == NULL) {
            node *n = new node;
            n->data = i;
            n->link = NULL;
            head = n;

            //head node initialized, and since it is ALSO the current and tail node (at this point), we must update our pointers
            current = n;
            tail = n;
            cout << "New node with data (" << i << ") created. \n---\n"; 

        } else {

        //If there are nodes in the list, create a new node with inputted value.
        node *n = new node;
        n->data = i;
        cout << "New node with data (" << i << ") created. \n"; 

        //Now, link the previous node to this node.
        current->link = n;
        cout << "Node with value (" << current->data << ") linked to this node with     value (" << i << ").  \n---\n";     

        //Finally, set our "current" pointer to this newly created node.
        current = n;
        }
    }

    /*
    listIterate()
    Iterates through the entire list and prints every element.
    */
    void listIterate() {

        //cursor
        node *p;

        //Start by printing the head of the list.
        cout << "Head - Value: (" << head->data << ") | Linked to: (" << head->link     << ") \n";

        p = head->link;
        cout << *p;

    }

}; 

int main() {

    LinkedList List;
    List.appendNode(0);
    List.appendNode(10);
    List.appendNode(20);
    List.appendNode(30);
    List.listIterate(); 

}

Now, I'll refer to this method, listIterate().

void listIterate() {

        //cursor
        node *p;

        //Start by printing the head of the list.
        cout << "Head - Value: (" << head->data << ") | Linked to: (" << head->link << ") \n";

        p = head->link; 
        cout << *p;

    }

The command cout << *p; throws an error and I believe this is why: At this point, p is pointing to head->link, which is another pointer which points to the link field of my head node. Now, I understand if I dereference p at this point in the program, there would be no actual value in head->link as it points to a variable.

To me, if I dereference p twice (**p), it should follow the pointer twice (p -> head->link -> The value of the second node in the linked list (10). However, dereferencing p twice throws this error.

LinkedListADT.cc:89: error: no match for ‘operator*’ in ‘** p’

Can anyone help me understand why this is the case? Is this an illegal operation? Is it performed in another way that I'm not familiar with?

Upvotes: 1

Views: 269

Answers (3)

Chris Dargis
Chris Dargis

Reputation: 6043

**p Does not "follow the pointer twice". The operation simply tries to dereference p twice.

p is a pointer to a node. The first dereference (*p) will evaluate to the node that was pointed to by p. The second dereference (**p) will cause an error, because a node is a struct and not a pointer and has no overloaded operator* defined.

If you wish to dereference the pointer to the next node:

*(p->link)

Upvotes: 1

moshbear
moshbear

Reputation: 3322

Your node class is missing an operator *, so the construct **p when p is of type node * is semantically ill-formed. To look at an example of overloading operator *, look at examples of implementing smart pointers.

Upvotes: 1

Jacob
Jacob

Reputation: 995

cout << *p tries to print a node object. Since no print operation is defined for node objects (ie. no operator<< for output streams), the attempt to print it fails. What you're probably looking for is:

cout << p->data;

For your second point, the statement can be broken down thus:

**p == *(*p)

So the first star dereferences p, returning a node. The second star attempts to dereference the result of that operation, but since a node is a struct and not a pointer, the compiler complains.

Hope this helps.

Upvotes: 3

Related Questions