c++ Linked List Memory Bug - c++

For an assignment i have to build this. I just can't seem to see what i am doing wrong. When I am trying to run this code I keep seeing the pointer that my linked list stores it's starting location get pointed to garbage right in the middle. I don't know if Visual Studio is just hazing me or if I am miss assigning a pointer somewhere.
This is the main class i use to run my code
#include "stdafx.h"
#include "Iterator.h"
#include "Node.h"
#include "List.h"
#include <iostream>
int main()
{
int input = 0;
List<double> salaryList;
std::cin >> input;
Node<double> tim(7.0, nullptr);
Node<double> sim(input, nullptr);
Node<double> jim(7.5, nullptr);
salaryList.Add_back(&jim);
salaryList.Add_back(&tim);
salaryList.Insert_front(&sim);
Iterator<double> checkSalaries=salaryList.begin();
//std::cout << "printing all elements in Iterator" << std::endl;
while (checkSalaries.Is_item()){
double x = (*checkSalaries).value;
std::cout << x << std::endl;
checkSalaries++;
}
system("PAUSE");
return 0;
}
This is the code for the LinkedList, i just named it List :
#include "Iterator.h"
#include "Node.h"
template <class t>
class List
{
private:
Node<t>* start=nullptr;
Node<t>* end=nullptr;
int size = 0;
public:
List() {
start = nullptr;
end = nullptr;
}
~List() {
}
void Insert_front(Node<t> * input) {
if (start != nullptr)
{
input->setPoint(start);
start = input;
size++;
}
else {
start = input;
}
if (start->point != nullptr && end == nullptr) {
end = start->point;
size++;
}
}
void Add_back(Node<t> * input) {
if (end != nullptr) {
Node<t> temp = (*end);
temp.setPoint(input);
end = input;
}
else {
if (start != nullptr) {
start->point=input;
end = input;
}
else {
start = input;
}
size++;
}
}
Iterator<t> begin() const
{
Node<t> tempNode = *start;
Iterator<t> temp(&tempNode);
return temp;
}
void Remove_all()
{
List<Node<t>> temp;
start = temp.start;
end = temp.end;
size = 0;
}
int Size() const {
return size;
}
};
This is the Node code:
template <class T>
class Node {
public:
T value;
Node<T> * point;
Node(T first, Node<T> * second)
{
value = first;
point = second;
}
Node()
{
value = NULL;
point = nullptr;
}
void setPoint(Node<T> * input) {
point = input;
}
};
I am going to include here two images the first is what it looks like just before it goes bad, and the next is what happens right after, it seems to occur fairly at random but i have found that using cout always triggers it so i commented out that line, though that didn't resolve the issue.
Good StateBad State

On my first review, it seems the local variable in begin method is creating the issue. Please check my code below. I have commented out the temporary variable created in the begin method and instead made use of the pointer start. This should solve the issue.
Iterator<t> begin() const
{
// Node<t> tempNode = *start; <-- A local variable is used here
// Iterator<t> temp(&tempNode); <-- address of local variable passed to iterator.
Iterator<t> temp(start);
return temp;
}

Related

How to find the largest value within a parameter using linked list?

I am tasked with implementing a new class function called bool List::largest_value(int &largest) within a given class List. The instruction is:
If the list is not empty, put the largest value in the largest
parameter and return true. If the list is empty, return false.
My question is, how do I find the largest value within a parameter?
Here is what I have so far for bool List::largest_value(int &largest):
// Fill in the functions at the bottom of this file
//
#include <iostream>
#include <climits>
using namespace std;
#include "list.h"
// on some machines member variables are not automatically initialized to 0
List::List()
{
m_head = NULL;
}
// delete all Nodes in the list
// since they are dynamically allocated using new, they won't go away
// automatically when the list is deleted
// Rule of thumb: destructor deletes all memory created by member functions
List::~List()
{
while (m_head)
{
Node *tmp = m_head;
m_head = m_head->m_next;
delete tmp;
}
}
// always insert at the front of the list
// Note: this works even in the SPECIAL CASE that the list is empty
void List::insert(int value)
{
m_head = new Node(value, m_head);
}
// iterate through all the Nodes in the list and print each Node
void List::print()
{
for (Node *ptr = m_head; ptr; ptr = ptr->m_next)
{
cout << ptr->m_value << endl;
}
}
void List::compare(int target, int &less_than, int &equal, int &greater_than)
{
Node *temp = m_head;
less_than = 0;
equal = 0;
greater_than = 0;
while(temp != NULL)
{
if(temp->m_value > target)
{
greater_than++;
}
else if(temp->m_value < target)
{
less_than++;
}
else if(temp->m_value == target)
{
equal++;
}
temp = temp-> m_next;
}
}
bool List::largest_value(int &largest)
{
Node *temp = m_head;
largest = INT_MIN;
if(temp == NULL)
{
return false;
}
while(temp != NULL)
{
if(temp->m_value > largest)
{
largest = temp->m_value;
}
temp = temp->m_next;
}
return true;
}
Here is the given class List:
class List
{
public:
List();
~List();
void insert(int value); // insert at beginning of list
void print(); // print all values in the list
void compare(int target, int &less_than, int &equal, int &greater_than);
bool largest_value(int &largest);
private:
class Node
{
public:
Node(int value, Node *next)
{m_value = value; m_next = next;}
int m_value;
Node *m_next;
};
Node *m_head;
};
Main.cpp:
#include <iostream>
using namespace std;
#include "list.h"
int main()
{
List list;
int value;
// read values and insert them into list
while (cin >> value)
{
list.insert(value);
}
int largest;
bool result = list.largest_value(largest);
if (result == false)
{
cout << "empty list" << endl;
return 1;
}
else
{
cout << "The largest value you entered is: " << largest << endl;
}
}
My code compiles and runs, however I keep receiving the output empty list. I honestly have no idea what I need to change in my bool List::largest_value(int &largest)function. I am still very new to linked lists. Any help would be appreciated

Vector returns negative size c++

For an exercize, I want to print out a tree data structure that is based on Node objects. This means, every object has a vector nodes that again holds other objects of type Node. But for some reason, when I let print out this->get_nr_children of the leaf nodes which basically just returns nodes.size(), I get completely random (negative) Integers where it should actually return 0. The even more interesting part: Every time I compile and execute, it prints out different Integers that alway are some low negative numbers. I do not have a clue what is happening!
Node.h
#include <string>
#include <vector>
using namespace std;
class Node
{
public:
virtual ~Node();
Node(string name = "");
string get_name() const;
void set_name(string& new_name);
int get_nr_children() const;
Node* get_child(int i) const;
void add_child(Node child);
void create_complete_tree(int nr_child_nodes, int tree_depth);
void print();
private:
string name;
static int node_id;
vector<Node> nodes = {};
};
Node.cpp
#include "node.h"
#include <sstream>
using namespace std;
Node::Node(string name) {
node_id++;
nodes = {};
if (name == "") {
stringstream str_sm;
str_sm << (node_id);
string node_id_str = str_sm.str();
this->name = "node_" + node_id_str;
} else {
this->name = name;
}
}
Node::~Node() {
nodes.clear();
// node_id = 0;
}
int Node::node_id = 0;
string Node::get_name() const {
return name;
}
void Node::set_name(string& new_name) {
this->name = new_name;
}
int Node::get_nr_children() const {
return nodes.size();
}
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
Node node = nodes[i];
Node *ptrNode = &node;
return ptrNode;
}
void Node::add_child(Node child) {
nodes.push_back(child);
}
void Node::create_complete_tree(int nr_child_nodes, int tree_depth) {
tree_depth--;
if (tree_depth <= 0) {
return;
}
for (int i = 0; i < nr_child_nodes; i++) {
Node* node = new Node();
this->add_child(*node);
node->create_complete_tree(nr_child_nodes, tree_depth);
}
}
void Node::print() {
cout << this->get_name() << "\n";
cout << "I got this many children " << this->get_nr_children();
for (int i = 0; i < this->get_nr_children(); i++) {
cout << "\t";
this->get_child(i)->print();
cout << "\n";
}
}
main.cpp
#include <iostream>
#include "node.cpp"
using namespace std;
int main() {
Node* root = new Node("root");
Node* left_child = new Node("left child");
Node* right_child = new Node("right child");
root->add_child(*left_child);
root->add_child(*right_child);
root->print();
return 0;
}
When I execute it I get:
root I got this many children 2 left child I got this many children
-62802357 right child I got this many children -62802357
Process finished with exit code 0
Your problem stems from
this->get_child(i)->print();
get_child returns a pointer to a local object. That object is destroyed when the function returns so the call to print on that returned Node is working with an already destroyed Node.
What you need to do is return a pointer directly to the vector element like
Node* Node::get_child(int i) /*const*/ { // cant be const for the return
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i];
}
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
Node node = nodes[i];
Node *ptrNode = &node;
return ptrNode;
}
Above you return a pointer to destroyed local Node node after get_child(i) returned. Correct code is below, that returns a pointer to a child in the vector.
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i];
}
main could be implemented much easier without pointers and memory leaks.
int main() {
Node root("root");
root.add_child(Node("left child"));
root.add_child(Node("right child"));
root.print();
return 0;
}
The problem is with the function Node* Node::get_child(int i) const. It returns a pointer to an object that is destroyed by the end of the function call.
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
Node node = nodes[i]; // <- node is a copy of nodes[i]
Node *ptrNode = &node;
return ptrNode; // <- returns a pointer to node
} // <- local objects are destroyed, including node
You must return a pointer to the actual element from the vector.
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i]; // <- Returns the address of the actual node
}

Find all matching nodes in linked list c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm writing a function to find all occurrences of a node in a linked list, the function will return the number of occurrences to the main function which will then display those occurrences. The program does compile but the it just freezes and nothing seems to happen when I enter the correct name to look for, if I enter the wrong name, which is not in the list, the findall function returns 0 and the rest of the program works fine. Please take a look.
main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "List.h"
void extra(list &);
/***********************************
* Main
* Test function - DO NOT CHANGE
***********************************/
void main()
{
list a;
extra(a);
}
/***********************************
* Extra Credit
* Test function - DO NOT CHANGE
***********************************/
void extra(list &a)
{ int i,n;
node_ptr map[4];
string first,last;
// Find node
cout << endl;
cout << "Enter First and Last name: ";
cin >> first >> last;
n = a.findall(first,last,map,4);
// Display forwards
cout << endl;
cout << "Find List\n--------------\n";
for (i = 0; i < n; i++)
{
map[i]->put(cout);
}
}
List.h
#include "Node.h"
#include <iostream>
#include <string>
using namespace std;
class list
{ public:
list(); // Empty constructor
~list(); // Destructor
int findall(string, string, node_ptr*, int);
node *find(string, string); // Locate a note
private:
node *head;
};
Node.h
#include <iostream>
#include <string>
using namespace std;
class list;
class node
{ friend list;
public:
node(); // Null constructor
~node(); // Destructor
void put(ostream &out); // Put
private:
string first,last;
int age;
node *next;
};
typedef node * node_ptr;
List.cpp
#include "List.h"
#include <iostream>
#include <string>
using namespace std;
/**
* Empty Constructor
*
*/
list::list()
{
head = nullptr;
}
/**
* Destructor Constructor
*
*/
list::~list()
{ if (head == nullptr) return;
node *p = head, *t;
while (p)
{
t = p;
p = p->next;
delete t;
}
head = nullptr;
}
/**
* Locate node
*
*/
node *list::find(string last, string first)
{
node *temp = head;
while (temp)
{
if (temp->first == first && temp->last == last) return temp;
temp = temp->next;
}
return nullptr;
}
/**
* Find all.
*
*/
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans;
ans = 0;
*map = find(first, last);
while (*map != NULL)
{
ans++;
*map = (*map)->next;
*map = find(first, last);
}
return ans;
}
Node.cpp
#include "Node.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
/**
* Empty Constructor
*
*/
node::node()
{
last = "";
first = "";
age = 0;
next = nullptr;
}
/**
* Destructor
*
*/
node::~node()
{ if (next != nullptr) next = nullptr;
}
/**
* Put
*
*/
void node::put(ostream &out)
{ out << setw(14) << left << last << setw(14) << first << setw(10) << age << endl;
}
I really appreciate your help. Thank you.
findall() freezes because it gets stuck in an endless loop.
If no matching node is found, the first call to find() returns nullptr and findall() exits.
But if a matching node is found, a loop is entered, calling find() to search the entire list all over again from the beginning. That will find the same node as before. Then you call find() again, and again, and so on.
To solve this issue, if find() returns a matching node, you need to pass the next node in the following call to find() so it can start searching where the previous search left off. Repeat until you reach the end of the list.
class list
{ public:
...
int findall(string first, string last, node_ptr *map, int n);
node_ptr find(string first, string last, node_ptr start = nullptr); // Locate a note
...
};
node_ptr list::find(string last, string first, node_ptr start)
{
node_ptr temp = (start) ? start : head;
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
return temp;
}
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans = 0;
node_ptr temp = nullptr;
while (ans < n)
{
temp = find(first, last, temp);
if (!temp) break;
*map++ = temp;
++ans;
temp = temp->next;
}
return ans;
}
Update: if you are not able to change the signature of find() then you will have to re-write findall() to duplicate what find() does:
class list
{ public:
...
int findall(string first, string last, node_ptr *map, int n);
node_ptr find(string first, string last); // Locate a node
...
};
node_ptr list::find(string last, string first)
{
node_ptr temp = head;
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
return temp;
}
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans = 0;
node_ptr temp = head;
while (ans < n)
{
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
if (!temp) break;
*map++ = temp;
++ans;
temp = temp->next;
}
return ans;
}

Linked list mistake at insertion

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?
Edit 1
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.
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.

Linked list problem with constructor and destructor

Hi
I have some issue regarding constructor and destructor. I have list class, which has two inner classes, one private class for the list nodes, and one public iterator class.
Now for the issue, I have written a non-member print function which uses the inner iterator class. When i use this non-member function it will end calling the destructor for the iterator. It doesn't end here though because for some reason it will also call for the list class's destructor. Which causes some problem when I want to print the list content again.
I don't understand why it call the list class destructor as well and wonder if someone kindly can tell me that, and how I should fix it.
I have attached all the code related to the problem
Main
#include <iostream>
#include "sorted_list.h"
#include "iterator.h"
using namespace std;
void list_print(ostream& os, sorted_list list)
{
sorted_list::iteratorn it(&list);
while( ! it.iterator_end())
{
os << "key = " << setw(3) << it.iterator_get_key() << ", "
<< "value = " << setw(5) << it.iterator_get_value() << endl;
it.iterator_next();
}
os << endl;
}
int main()
{
sorted_list a;
a.insert(4,4);
a.insert(5,5);
list_print(cout,a);
list_print(cout,a);
}
sorted_list.cc
#include "sorted_list.h"
sorted_list::sorted_list()
{
cout << "construct sorted_list" << endl;
this->first = 0;
}
sorted_list::~sorted_list()
{
cout << "destruct sorted_list" << endl;
destroy(this->first);
}
void sorted_list::destroy(list_link* item)
{
cout << "destroy list_link" << endl;
if(item)
{
destroy(item->next);
delete item;
}
}
void sorted_list::insert(int key, double value)
{
list_link *curr;
list_link *prev = 0;
curr = first;
while(curr)
{
if(value < curr->value)
break;
prev = curr;
curr = curr->next;
}
if(this->first == 0 || prev == 0) //if empty or add first
{
//first = create(key, value, this->first);
first = new list_link(key, value, this->first);
}
else if(curr == 0)
{
//prev->next = create(key, value, 0);
prev->next = new list_link(key, value, 0);
}
else
{
//prev->next = create(key, value, curr);
prev->next = new list_link(key, value, curr);
}
}
void sorted_list::remove(my_key_type key)
{
list_link *curr = first;;
list_link *prev = 0;
while(curr)
{
if(curr->key == key)
{
list_link *remove;
if(prev == 0)
{
first = curr->next;
delete curr;
curr = first;
}
else
{
remove = curr;
curr = curr->next;
prev->next = curr;
delete remove;
}
continue;
}
prev = curr;
curr = curr->next;
}
}
sorted_list::list_link* sorted_list::clone(list_link* item)
{
list_link* copyItem= new list_link(item->key,item->value,0);
if(item->next!= 0)
copyItem->next=clone(item->next);
return copyItem;
// ADD YOUR CODE HERE ( 4 well formatted lines in reference solution )
}
void sorted_list::copy(sorted_list* my_this_destination)
{
if (my_this_destination->first == 0) // copy if empty
{
cout << "Copy" << endl;
//list_destroy(my_this_destination);
my_this_destination->first = clone(first);
}
}
double sorted_list::find(int key)
{
list_link *travel = this->first;
while(travel)
{
cout << travel->key << "==" << key << endl;
if(travel->key == key)
return travel->key;
travel = travel->next;
}
return -1;
}
int sorted_list::size()
{
list_link *travel = this->first;
int i = 0;
while( travel )
{
travel = travel->next;
i++;
}
return i;
}
sorted_list.h
#ifndef _SORTED_LIST_H_
#define _SORTED_LIST_H_
#include <iostream>
#include <iomanip>
using namespace std;
typedef int my_key_type;
typedef double my_value_type;
class sorted_list
{
public:
sorted_list();
~sorted_list();
void insert(int key, double value);
void remove(my_key_type key);
void copy(sorted_list* my_this_destination);
void destroy();
void init(struct my_list* my_this);
void print();
void print2();
double find(int key);
int size();
private:
class list_link // An inner class inside sorted_list
{
public:
list_link (my_key_type key, my_value_type value, list_link* next = 0);
~list_link();
my_key_type key;
my_value_type value;
list_link *next;
};
list_link* first;
list_link* clone(list_link* item);
void destroy(list_link* item);
// More declarations
public:
class iteratorn
{
public:
iteratorn();
~iteratorn();
iteratorn(sorted_list *item);
list_link* list_begin();
bool iterator_end();
void iterator_next();
int iterator_get_key();
double iterator_get_value();
private:
sorted_list::list_link* current;
};
};
#endif
iteratorn.cc
#include "iterator.h"
#include "sorted_list.h"
sorted_list::iteratorn::iteratorn()
{
}
sorted_list::iteratorn::iteratorn(sorted_list *list)
{
cout << "construct iteratorn" << endl;
this->current = list->first;
}
sorted_list::iteratorn::~iteratorn()
{
cout << "destruct iteratorn" << endl;
}
sorted_list::list_link* sorted_list::iteratorn::list_begin()
{
return current;
}
void sorted_list::iteratorn::iterator_next()
{
current = current->next;
}
int sorted_list::iteratorn::iterator_get_key()
{
return current->key;
}
double sorted_list::iteratorn::iterator_get_value()
{
return current->value;
}
list_link.cc
#include "sorted_list.h"
sorted_list::list_link::list_link(my_key_type key, my_value_type value, list_link* next)
{
this->key = key;
this->value = value;
this->next = next;
}
sorted_list::list_link::~list_link()
{
cout << "list_link destructor" << endl;
}
Your function void list_print(ostream& os, sorted_list list) takes a sorted_list parameter by copy. A quick and dirty fix (that you should do anyways for performance reasons) is the following:
void list_print(ostream& os, const sorted_list& list)
Now, your iteratornclass takes a mutable list, so this won't work as you expect. You will have quite a few methods to change to make this work.
In any case, your real problem is the lack of a proper copy-constructor. Right now, when you "copy" a list, both end up sharing the same elements, but your destructor is written as if each list owns it's own nodes. Define a proper copy operation and it will solve your problem.
More elaborate help on how to solve the problem: (untested)
Change signature:
void list_print(ostream& os, const sorted_list& list);
Declare + define copy constructor:
sorted_list::sorted_list (const sorted_list& other);
Change iteratorn interface to support a const sorted_list:
class sorted_list::iteratorn
{
public:
iteratorn();
~iteratorn();
iteratorn(const sorted_list& list);
const list_link* list_begin() const;
bool iterator_end() const;
void iterator_next();
int iterator_get_key() const;
double iterator_get_value() const;
private:
// You *should* make this `const` but it is not required.
sorted_list::list_link* current;
};
As you can see, the changes are rather minimal, but need to be applied in various places.
const + non-const iterators:
I applied changes here based on the fact that your iteratorn was currently only defining read-only operations on your sorted_list. If you want to support write access to allow changing the value stored in list nodes (never allow changing the key or you won't have a sorted list anymore), you should define two iterator classes. See the STL iterator interface for more details.
You're copying the list by value, so the local copy in list_print() destructs at end of scope. Pass it by const-reference instead.
This in turn means you will have to change your sorted_list to support working with const lists. In particular you need to have a function that returns a const iterator pointing to the beginning of the list:
sorted_list::const_iteratorn begin() const
{
// returns a const_iteratorn pointing at the beginning of this list
}
Notice you need a new kind of iterator: a const_iteratorn, which promises it won't change the list.
Then, inside print_list() initialize a const_iteratorn with the start iterator that sorted_list returns, by copy:
sorted_list::const_iteratorn s(list.begin());
Finally create a second iterator instance that initializes with an end iterator coming from a member function of sorted_list, similar to the begin() function. This will maintain the const-correctness in print_list().
sorted_list::const_iteratorn e(list.end());
while( s != e ) { // two iterators should be able to compare
// ...
s.iterator_next(); // consider ++s
}
Also, as André mentioned, the fact you don't have a proper copy-constructor and assignment operator is a severe issue. Make sure that copying a sorted_list means copying all its elements, so that the new object owns its own list of elements. Do recall the Rule of Three.