1
votes

I am learning about smart pointers and tried implementing in a linked list.the code of the node, List and main files are as follows:

Node.h

 #pragma once
 #include <memory>

class Node {
    int data;
    std::shared_ptr<Node> next;

public:
    Node(int);
    int getValue();
    void setValue(int);
    std::shared_ptr<Node> Next();
};

Node.cpp

#include "stdafx.h"
#include "Node.h"

Node::Node(int value) : data(value){}

int Node::getValue(){
    return data;
}

void Node::setValue(int value){
    data = value;
}

std::shared_ptr<Node> Node::Next(){
    return next;
}

List.h

class List{
    std::shared_ptr<Node> head;
    public:
        //List();
        bool isEmpty();
        void insertNode(int value);
        void printList();

};

List.cpp

#include "stdafx.h"
#include "List.h"
#include <iostream>

bool List::isEmpty(){
    return (head == nullptr) ? true : false;
}

void List::insertNode(int value){

    Node newNode(value);
    if (isEmpty()){
        head = std::make_shared<Node>(newNode);
    }

    else{
        newNode.Next()=head; //Problem here
        head = std::make_shared<Node>(newNode);
    }
}
void List::printList(){
    while (head->Next() != nullptr){
        std::cout << head->getValue();
    }
    std::cout << head->getValue();
}

main.cpp

#include "stdafx.h"
#include "List.h"
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{
    List newSingleList;
    if (newSingleList.isEmpty())
        std::cout << "The list is curently empty\n";
    newSingleList.insertNode(10);
    newSingleList.insertNode(20);
    newSingleList.printList();
    return 0;
}

The problem is that the value in the List.cpp file at "the commented line" the debugger shows that even after the assignment the value is empty and the node actually points to nothing. then the head in the next line is set to the new node which then basically points to a different memory address without linking to the previous Node .

Why is this ? what am I missing ?

Here is the debugger snapshot: as said the next points to empty after stepover the breakpoint. according to the code the statement at the breakpoint must assign the next pointer to the previous head/node.

https://www.dropbox.com/s/yaybpukacx53fq1/Screenshot%202015-03-08%2011.33.08.png?dl=0

2
Don't see the new smart pointers as a replacement for normal pointers, instead you should look at them from a resource ownership perspective. Can a resource have only one owner? Then use std::unique_ptr. Can a resource be shared? Then use std::shared_ptr.Some programmer dude
A couple of other points: The result of the expression head == nullptr is already a boolean true or false value. And your printList function will run forever printing the same node value over and over.Some programmer dude

2 Answers

0
votes

This isn't a shared pointer problem at all. Based on your usage, I think Next is supposed to be returning a reference to next, but instead you're returning a copy.

(if Next is supposed to return a copy, then you can't use Next at all to modify the value of next, so you'll have to do that another way)

0
votes

Introduction

The problem is that you are assigning to a temporary returned by std::shared_ptr<Node> Node::Next (), ie. you are not updating the data-member next in newNode on the following line:

newNode.Next () = head;

The above is semantically equivalent to the below, because of how Node::Next is declared (you are returning a copy - and not a reference to the data-member):

{
  auto __temp = newNode.Next ();
       __temp = head;
}

How do I fix it?

Instead of returning a copy of next from Node::Next, make it return a reference to the data-member:

class Node {
    int data;
    std::shared_ptr<Node> next;

public:
    Node(int);
    int getValue();
    void setValue(int);
    std::shared_ptr<Node>& Next();
};

std::shared_ptr<Node>& Node::Next(){
    return next;
}