binaryTree (works in visual studio, but not in visual code) - c++

I have Segmentation Fault to this line "if (value >= current->getValue())" (in method "chooseNextPosition") in Visual Code, I believe the problem is with the destructor.
I used a method with the same code, instead of a destructor, and it works. Furthermore, my code also works in Visual Studio and is compiled by g++, without any problems.
Here is the code:
#include <iostream>
class Node
{
private:
int value;
Node* right;
Node* left;
Node* prev;
public:
Node(int value) :
value{ value },
right{ nullptr },
left{ nullptr },
prev{ nullptr }
{}
Node(const Node& node) :
value{ node.value },
right{ nullptr },
left{ nullptr },
prev{ nullptr }
{}
void setValue(const int& new_value)
{
this->value = new_value;
}
void setRight(Node* new_right)
{
this->right = new_right;
this->right->prev = this;
}
void setLeft(Node* new_left)
{
this->left = new_left;
this->left->prev = this;
}
const int& getValue() const
{
return this->value;
}
Node* getRight()
{
return this->right;
};
Node* getLeft()
{
return this->left;
}
Node* getPrev()
{
return this->prev;
};
friend std::ostream& operator<<(std::ostream& os, const Node& node);
~Node()
{
if (this->right != nullptr)
delete this->right;
if (this->left != nullptr)
delete this->left;
value = 0;
}
};
std::ostream& operator<<(std::ostream& os, const Node& node)
{
return os << node.getValue();
}
class Tree
{
private:
Node* root;
Node* chooseNextPosition(Node* current, int value) const
{
if (current == nullptr)
return nullptr; //TODO throw exception
` if (value >= current->getValue())`
{
current = current->getRight();
}
else {
current = current->getLeft();
}
return current;
}
public:
Tree() = default;
Node* getRoot()
{
return this->root;
}
void insert(int value)
{
if (this->root == nullptr)
{
this->root = new Node(value);
return;
}
Node* current{ nullptr };
Node* next_current{ this->root };
while (next_current != nullptr)
{
current = next_current;
next_current = chooseNextPosition(current, value);
}
if (value >= current->getValue())
{
current->setRight(new Node(value));
}
else
{
current->setLeft(new Node(value));
}
}
const Node* getNext(Node* current) const // ?
{
if (current == nullptr)
return nullptr; //TODO throw exception
return(current->getLeft());
}
Node* find(int value, Node* root) //this->root = root;
{
Node* current{ root };
if (root == nullptr)
{
std::cout << "element doesn`t exist" << std::endl;
return nullptr;
}
if (current->getValue() == value)
return current;
current = chooseNextPosition(current, value);
find(value, current);
}
void printTree(Node* root) //root = this->root
{
if (root != nullptr)
{
printTree(root->getLeft());
std::cout << root->getValue() << " ";
printTree(root->getRight());
}
}
void dl()
{
if (root != nullptr)
delete(this->root);
}
~Tree()
{
if (root != nullptr)
delete(this->root);
}
};
int main()
{
Tree tree;
tree.insert(45);
tree.insert(55);
tree.insert(34);
tree.insert(1);
tree.insert(28);
tree.printTree(tree.getRoot());
std::cout << std::endl;
Node* tmp = tree.find(1, tree.getRoot());
std::cout << tree.find(1, tree.getRoot())->getPrev()->getValue() << std::endl;
}

You forgot to initialize root to nullptr in the default constructor for Tree.
Additionally, you forgot to return the result of the recursive call for find(...).

Related

error: new initializer expression list treated as compound expression [-fpermissive]

I am trying to write a playlist method for songs in c++, however, I keep running into frequent errors.
template <typename T>
struct cir_list_node
{
T* data;
cir_list_node *next, *prev;
//destructor
~cir_list_node() {
delete data;
}
};
template <typename T>
struct cir_list
{
public:
using node = cir_list_node<T>; // renaiming for local use
using node_ptr = node*;
private:
node_ptr head;
size_t n;
public:
// basic constructor and size function
cir_list(): n(0) // initiator list
{
head = new node(NULL,NULL,NULL); //dummy node
head->next = head; // circular list wraps around
head->prev = head;
}
cir_list(const cir_list& other): cir_list()
{
// insert in reverse order (okay because list is circular)
for(const auto& i : other)
insert(i);
}
cir_list(const std::initializer_list<T>& il): head(NULL), n(0)
{
//insert in reverse order
for(const auto& i : il)
insert(i);
}
~cir_list()
{
while(size())
{
erase(head->data);
}
}
size_t size() const
{
return n;
}
void insert(const T& value)
{
node_ptr newNode = new node(new T(value),NULL,NULL);
n++;
auto dummy = head->prev;
dummy->next = newNode;
newNode->prev = dummy;
if(head == dummy) {
dummy->prev = newNode;
newNode->next = dummy;
head = newNode;
return;
}
newNode->next = head;
head->prev = newNode;
head = newNode;
return;
}
void erase(const T& value)
{
auto cur = head, dummy = head->prev;
while (cur != dummy){
if(*(cur->data) == value){
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
if(cur == head)
head = head->next;
delete cur;
n--;
return;
}
cur = cur->next;
}
}
struct cir_list_it
{
private:
node_ptr ptr;
public:
cir_list_it(node_ptr p) : ptr(p)
{}
T& operator*()
{
return *(ptr->data);
}
node_ptr get()
{
return ptr;
}
cir_list_it& operator++() // prefix
{
ptr = ptr->next;
return *this;
}
cir_list_it operator++(int) // postfix
{
cir_list_it it = *this;
++(*this);
}
cir_list_it& operator--() //prefix
{
ptr = ptr->prev;
return *this;
}
cir_list_it operator--(int) // postfix
{
cir_list_it it = *this;
--(*this);
return it;
}
friend bool operator == (const cir_list_it& it1, const cir_list_it& it2)
{
return it1.ptr == it2.ptr;
}
friend bool operator != (const cir_list_it& it1, const cir_list_it& it2)
{
return it1.ptr != it2.ptr;
}
};
cir_list_it begin()
{
return cir_list_it {head};
}
cir_list_it end()
{
return cir_list_it {head->prev};
}
cir_list_it end() const
{
return cir_list_it{head->prev};
}
};
struct playlist
{
cir_list<int> list;
void insert(int song)
{
list.insert(song);
}
void erase(int song)
{
list.erase(song);
}
void loopOnce()
{
for(auto& song : list){
std::cout << song << " ";
}
std::cout << std::endl;
}
};
int main()
{
playlist pl;
pl.insert(1);
pl.insert(2);
std::cout << "Playlist: ";
pl.loopOnce();
playlist pl2 = pl;
pl2.erase(2);
pl2.insert(3);
std::cout << "Second playlist";
pl2.loopOnce();
}
Errors
1 and 2:
3 and 4:
It seems there is a typo
struct cir_list_node
{
T* data;
cir_list_node *next, *prev;
//destructor
~cir_list_node() {
delete data;
}
};
You forgot to prefix this declaration with
template <typename T>
This template structure declaration declares an aggregate.
You can not initialized it with an expression inside parentheses like
head = new node(NULL,NULL,NULL);
Instead you need to write using braces
head = new node { NULL, NULL, NULL };
or as you are writing a C++ program then
head = new node { nullptr, nullptr, nullptr };
It seems there is a typo
struct cir_list_node
{
T* data;
cir_list_node *next, *prev;
//destructor
~cir_list_node() {
delete data;
}
};

cannot convert 'this' pointer from 'const List<T>' to 'List<T> &'

I implement a doubly linked list. Then I used that linked list as container for stack. but I get Error C2662 'const T &List::last_elem(void)': cannot convert 'this' pointer from 'const List' to 'List &'. I tried to return as a value but it didnt work. I dont understand whether compiler points wrong point.
template<typename T>
struct Node
{
T data;
Node* next;
Node* prev;
Node() :data{ 0 } { next = nullptr; prev = nullptr; }
};
template<typename T>
class List
{
private:
Node<T>* headNode;
Node<T>* tailNode;
public:
List()
{
headNode = new Node<T>;
tailNode = new Node<T>;
headNode->next = tailNode;
tailNode->prev = headNode;
}
~List()
{
Node<T>* current = headNode;
while (current)
{
Node<T>* tempNode = current;
current = current->next;
delete tempNode; cout << "\nDeleting List!!!";
}
}
bool empty()
{
return (headNode->next == tailNode);
}
const T &last_elem()
{
return tailNode->prev->data;
}
const T &first_elem()
{
return headNode->next->data;
}
void remove_first()
{
Node<T>* tempNode = headNode;
headNode = tempNode->next;
delete tempNode; cout << "\nDeleting Node!!!";
headNode->prev = nullptr;
}
void remove_last()
{
Node<T>* tempNode = tailNode;
tailNode = tempNode->prev;
delete tempNode; cout << "\nDeleting Node!!!";
tailNode->next = nullptr;
}
void add_front(T d)
{
headNode->data = d;
Node<T>* tempNode = new Node<T>;
tempNode->next = headNode;
headNode->prev = tempNode;
headNode = tempNode;
}
void add_end(T d)
{
tailNode->data = d;
Node<T>* tempNode = new Node<T>;
tempNode->prev = tailNode;
tailNode->next = tempNode;
tailNode = tempNode;
}
void print_list()
{
Node<T>* current = headNode->next;
while (current)
{
cout << current->data << "|-> ";
current = current->next;
}
}
void reverse_print_list()
{
Node<T>* current = tailNode->prev;
while (current)
{
cout << current->data << "|-> ";
current = current->prev;
}
}
};
template<typename T>
class ListStack
{
private:
List<T> stacklist;
int index;
public:
class StackException
{
private:
string errMessage;
public:
StackException(string err) :errMessage(err) {}
string getErrMessage() { return errMessage; }
};
ListStack():index { -1 }{}
int size() const // number of items in the stack
{
return index + 1;
}
bool empty() const // is the stack empty?
{
return (index == -1);
}
const T& top() const throw(StackException) // the top element
{
if (empty())throw StackException(string("Stack is empty!!!"));
return stacklist.last_elem();
}
void push(const T& e) // push element onto stack
{
stacklist.add_end(e);
++index;
}
void pop() throw(StackException) // pop the stack
{
if (empty())throw StackException(string("Stack is empty!!!"));
stacklist.remove_last();
--index;
}
};
int main()
{
try
{
ListStack<int> myls;
myls.push(5);
myls.push(8);
myls.push(9);
myls.push(12);
myls.push(17);
cout << myls.top() << endl;
myls.pop();
myls.pop();
myls.pop();
myls.pop();
myls.pop();
myls.pop();
myls.pop();
myls.pop();
myls.pop();
}
catch (ListStack<int>::StackException se)
{
cout << se.getErrMessage();
}
return 0;
}
Make last_elem() a const qualified with:
const T &last_elem() const
// ^^^^^
The Problem is:
const T& top() const throw(StackException)
remove the second const to
const T& top() throw(StackException)
And you should be fine.
(this is because the called last_elem() method is not const since constant methods can obviously not call non-constant methods, so making that one const would work too).

Linked List Copy/Move semantic C++

so I have this code for linked list below. I need to create copy/move constructors and operators.
I am having troubles how to make it the right way.
I know the code isn't perfect, I will appreciate all tips, but I want to focus mainly on copy/move semantic.
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
class List {
class Node {
Node* next;
string text;
int index;
friend class List;
public:
Node(const string& value, int i) : next(nullptr), index(i), text(value) {}
friend ostream& operator<< (ostream& wy, const Node& wzl) {
if (wzl.next) return wy << wzl.text << ", " << *wzl.next;
else return wy << wzl.text;
}
};
Node* head;
int _size(Node* node, int size = 0) {
if (node == NULL) {
return size;
} else {
_size(node->next, size+1);
}
}
void _insert(Node* node, const string& value, int index) {
if (node->next == NULL || node->next->index > index) {
if (node->index == index) {
node->text = value;
} else {
Node* element = new Node(value, index);
element->next = node->next;
node->next = element;
}
} else {
_insert(node->next, value, index);
}
}
string _read(Node* node, int index) {
if (node->next != NULL && node->next->index <= index) {
return _read(node->next, index);
} else if (node->index == index) {
return node->text;
} else {
throw invalid_argument("No such index");
}
}
void _remove(Node* node, int index) {
if (node->next != NULL && node->next->index < index) {
_remove(node->next, index);
} else if (node->next->index == index) {
Node* temp;
if (node->next->next != NULL) {
int temp_index = node->next->next->index;
temp = new Node(node->next->next->text, temp_index);
if (node->next->next->next != NULL) {
temp->next = node->next->next->next;
} else {
temp->next = NULL;
}
temp->index = node->next->next->index;
} else {
temp = nullptr;
}
delete node->next;
node->next = temp;
} else {
throw invalid_argument("No such index");
}
}
public:
List() : head(nullptr){};
List(const List &lst) : head(nullptr) {
Node* tmp_lst = lst.head;
Node* tmp_this = this->head;
while (tmp_lst != NULL) {
// cerr << this->head->text;
tmp_this = new Node(tmp_lst->text, tmp_lst->index);
tmp_this = tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
List(List&& lst);
List(initializer_list<string> lst) : List() {
Node* tmp;
int pos = 0;
for (auto element : lst) {
if (this->head != NULL){
tmp->next = new Node(element, pos);
tmp = tmp->next;
pos++;
} else {
this->head = new Node(element, pos);
tmp = this->head;
pos++;
}
}
};
List& operator= (const List& lst) {
if (this != &lst) {
delete this->head;
this->head = nullptr;
Node* tmp_lst = lst.head;
Node* tmp_this = this->head;
while (tmp_lst != NULL) {
tmp_this = new Node(tmp_lst->text, tmp_lst->index);
tmp_this = tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
return *this;
}
List& operator= (List&& lst);
~List(){
delete head;
};
void insert(const string& value, int pos) {
if (pos < 0) {
throw invalid_argument("Position cant be negative");
}
if (this->head == NULL) {
Node* new_head = new Node(value, pos);
this->head = new_head;
} else if (this->head->index > pos) {
Node* new_head = new Node(value, pos);
new_head->next = this->head;
this->head = new_head;
} else {
_insert(this->head, value, pos);
}
}
string read(int pos) {
return _read(this->head, pos);
}
int size() {
return _size(this->head);
}
void remove(int pos) {
return _remove(this->head, pos);
}
public:
friend ostream& operator<< (ostream& wy, const List& lst) {
if (lst.head) return wy << "(" << *lst.head << ")";
else return wy << "()";
}
};
int main() {
return 0;
}
You List copy-constructor is severely flawed:
You initialize tmp_this to the value of this->head which is a null pointer
The above doesn't matter because the first thing you do in the loop is reassign tmp_this to point to a new Node object.
Then you immediately discard that pointer, by reassigning tmp_this to point to tmp_this->next which is a null pointer.
And you don't link anything into the list.
A working function could look something like
List(const List &lst) : head(nullptr) {
Node* tmp_lst = lst.head;
Node** tmp_current = &head;
while (tmp_lst != NULL) {
Node* tmp_this = new Node(tmp_lst->text, tmp_lst->index);
// Would prefer to use the copy-constructor here too, instead of the above
// Node* tmp_this = new Node(tmp_lst);
// This links the new node into the end of the list
*tmp_current = tmp_this
tmp_current = &tmp_this->next;
tmp_lst = tmp_lst->next;
}
}

c++ how implement iterator for a doubly linked list

I am using this text book
http://cpp.datastructures.net
chapter 5 iterator usage:
http://cpp.datastructures.net/source/ch05/CPP/IteratorPrint.cpp-DSACiterator.html
here is how i implement it (the ObjectIterator class)
#include <iostream>
using namespace std;
class PositionException {
protected:
string message;
public:
PositionException(const string &m) {
message = m;
}
void print() {
cout << message << endl;
}
};
template <typename T>
class NodeList {
protected:
struct Node {
Node *prev;
Node *next;
T item;
Node(T i = T(), Node *p = NULL, Node *n = NULL) : item(i), prev(p), next(n) {}
};
typedef Node * NodePtr;
public:
class Position {
protected:
NodePtr node;
public:
bool isNull() {
return node == NULL;
}
Position(NodePtr n = NULL) : node(n) {}
T& element() {
return node->item;
}
friend class NodeList;
};
class ObjectIterator {
protected:
NodePtr node;
public:
ObjectIterator(NodePtr n = NULL) : node(n) {}
bool hasNext() {
if (node->next == NULL) {
return false;
}
if (node->next->next == NULL) {
return false;
}
return true;
}
ObjectIterator next() {
return ObjectIterator(node->next);
}
T& element() {
return node->item;
}
friend class NodeList;
};
protected:
int sz;
NodePtr header;
NodePtr trailer;
public:
NodeList() {
header = new Node();
trailer = new Node();
header->next = trailer;
trailer->prev = header;
sz = 0;
}
bool isEmpty() const {
return size() == 0;
}
int size() const {
return sz;
}
bool isFirst(const Position& p) const {
return p.node->prev == header;
}
bool isLast(const Position& p) const {
return p.node->next = trailer;
}
Position first() const {
if (isEmpty()) {
throw PositionException("no first for empty list");
}
return Position(header->next);
}
Position last() const {
if (isEmpty()) {
throw PositionException("no last for emtpy list");
}
return Position(trailer->prev);
}
Position before(const Position& p) const{
if (p.node->prev == header) {
throw PositionException("already the first element, nothing before it");
}
return Position(p.node->prev);
}
Position after(const Position& p) const{
if (p.node->next == trailer) {
throw PositionException("already the last element, nothing after it");
}
return Position(p.node->next);
}
Position insertAfter(const Position& p, const T& o) {
NodePtr node = new Node(o, p.node, p.node->next);
p.node->next->prev = node;
p.node->next = node;
sz++;
return Position(node);
}
Position insertBefore(const Position& p, const T& o) {
NodePtr node = new Node(o, p.node->prev, p.node);
p.node->prev->next = node;
p.node->prev = node;
sz++;
return Position(node);
}
void remove(const Position& p) {
p.node->prev->next = p.node->next;
p.node->next->prev = p.node->prev;
sz--;
delete p.node;
}
void removeFirst() {
remove(first());
}
void removeLast() {
remove(last());
}
void replaceElement(const Position& p, const T& element) {
if (p.isNull()) {
throw PositionException("p is null");
}
p.node->item = element;
}
Position insertFirst(const T& o) {
NodePtr node = new Node(o, header, header->next);
header->next->prev = node;
header->next = node;
sz++;
return Position(node);
}
Position insertLast(const T& o) {
NodePtr node = new Node(o, trailer->prev, trailer);
trailer->prev->next = node;
trailer->prev = node;
sz++;
return Position(node);
}
void copyFrom(const NodeList<T>& nl) {
sz = nl.sz;
if (nl.sz > 0) {
Position p0 = nl.first();
Position p = insertFirst(p0.node->item);
while (!nl.isLast(p0)) {
p0 = nl.after(p0);
insertAfter(p, p0.node->item);
}
}
}
void emptyList() {
while (!isEmpty()) {
removeFirst();
}
}
~NodeList() {
emptyList();
delete header;
delete trailer;
}
NodeList<T>& operator=(const NodeList<T>& nl) {
emptyList();
copyFrom(nl);
}
NodeList(const NodeList<T>& nl) {
emptyList();
copyFrom(nl);
}
void print() {
cout << "size is: " << size() << endl;
if (size() > 0) {
ObjectIterator i = elements();
while (i.hasNext()) {
cout << i.element() << "\t";
i = i.next();
}
cout << endl;
}
}
ObjectIterator elements() {
if (isEmpty()) {
throw PositionException("iterator error: empty");
}
return ObjectIterator(header->next);
}
void swapItems(const Position& p1, const Position& p2) {
T temp = p1.node->item;
p1.node->item = p2.node->item;
p2.node->item = temp;
}
};
If i don't use the iterator, the following code for printing is correct
void print() {
if (size() > 0) {
NodePtr n = header->next;
while (n != trailer) {
cout << n->item << "\t";
n = n->next;
}
cout << endl;
}
}
If I use the iterator for the print function
void print() {
cout << "size is: " << size() << endl;
if (size() > 0) {
ObjectIterator i = elements();
while (i.hasNext()) {
cout << i.element() << "\t";
i = i.next();
}
cout << endl;
}
}
one of the node is missing.
The book does not provide the correct way to implement the iterator

Linked list outputting different values to cout

I'm writing a linked list container for my homework. Using Qt 4.7 and gcc 4.4, I've found some problems in the code that I guess they are related to memory management or garbage collection.
After using the << operator to display the list, all data of list is changed. for example, after construction and setting a list like l,
std::cout<<l<<std::endl;
std::cout<<l<<std::endl;
prints:
Data = [-10, 3, 2, 8, 1, -1, -2, ] // this is correct
Data = [0, 149560240, 149560192, 149558336, 149560256, 149558320, 149560208, ]
My linked list is:
#ifndef LINKEDLIST1_H_
#define LINKEDLIST1_H_
#include <iostream>
template<class T> class LinkedList1;
template<class T> class Node;
template<class T>
class Node
{
friend class LinkedList1<T> ;
public:
Node(const T& value) :
Data(value), Next(NULL)
{
}
Node() :
Next(NULL)
{
}
T Data;
Node* Next;
};
template<class T>
class LinkedList1
{
public:
LinkedList1() :
size(-1), first(NULL)
{
}
~LinkedList1()
{
Node<T>* i = this->first;
Node<T>* j = this->first;
while(j!=NULL)
{
j=i->Next;
delete i;
i=j;
}
}
// Operations on LinkedList
Node<T>* First()
{
return first;
}
int Size()
{
return size + 1;
}
int Count()
{
int size = 0;
Node<T>* current = this->firstFirst();
while(current != NULL)
{
size++;
current = current->Next;
}
this->size = size;
return this->Size();
}
bool IsEmpty()
{
return this->Size() == 0;
}
void Prepend(Node<T>* value) //O(1)
{
value->Next = this->first;
this->first = value;
this->size++;
}
void Prepend(const T& value) //O(1)
{
Node<T>* item = new Node<T>(value);
item->Next = this->first;
this->first = item;
this->size++;
}
void Append(Node<T>* value)
{
if(this->IsEmpty())
{
this->first = value;
this->size++;
}
else
{
Node<T>* current = this->First();
while(current->Next != NULL)
current = current->Next;
current->Next = value;
value->Next = NULL;
this->size++;
}
}
void Append(const T& value)
{
Node<T>* temp= new Node<T>(value);
this->Append(temp);
}
void Insert(Node<T>* location, Node<T>* value) //O(n)
{
Node<T>* current = this->first;
Node<T>* before = current;
while(current != NULL)
{
before = current;
current = current->Next;
if(current == location)
{
before->Next = value;
value->Next = current;
this->size++;
break;
}
}
}
void Insert(Node<T>* location, const T& value)
{
Node<T>* temp = new Node<T>(value);
this->Insert(location,temp);
}
Node<T>* Pop()
{
if(this->IsEmpty())
return NULL;
else
{
Node<T>* current = this->first;
Node<T>* before = current;
while(current->Next != NULL)
{
before = current;
current = current->Next;
before->Next = current;
}
before->Next = NULL;
this->size--;
return current;
}
}
Node<T>* PopF()
{
if(!this->IsEmpty())
{
Node<T>* head = this->first;
this->first = this->first->Next;
this->size--;
return head;
}
else
return NULL;
}
Node<T>* Remove(Node<T>* location)
{
// validating by IsEmpty is not necessary for this operation,
// while statement's condition guarantees validation
Node<T>* current = this->first;
Node<T>* before = current;
while(current != NULL)
{
before = current;
current = current->Next;
before->Next = current;
if(current == location)
{
before->Next = current->Next;
current->Next=NULL;
return current;
}
}
return NULL; // Not found...
}
void Inverse()
{
if(this->IsEmpty())
return;
else
{
Node<T>* r = NULL;
Node<T>* q = this->first;
Node<T>* p = this->first;
while(q != NULL)
{
p = p->Next;
q->Next = r;
r = q;
q = p;
}
this->first = r;
}
}
// Ordered insertion. implement this: foreach i,j in this; if i=vale: i+=vale, break; else if i<=value<=j: this.insert(j,value),break
friend std::ostream& operator<<(std::ostream& out, const LinkedList1 item)
{
out<<"Data = [";
Node<T>* current = item.first;
while(current != NULL)
{
out << current->Data << ", ";
current = current->Next;
}
out<<"]";
return out;
}
void HelperOutput(std::ostream& out, const LinkedList1 item) const
{
out<<item;
}
Node<T>* operator[](const int& index)
{
int i=0;
Node<T>* current = this->first;
while(i<=index && current!=NULL)
{
if(i=index)
return current;
else
{
i++;
current=current->Next;
}
}
}
public:
int size;
Node<T>* first;
};
#endif /* LINKEDLIST1_H_ */
friend std::ostream& operator<<(std::ostream& out, const LinkedList1 item)
{
out<<"Data = [";
Node<T>* current = item.first;
while(current != NULL)
{
out << current->Data << ", ";
current = current->Next;
}
out<<"]";
return out;
}
first item in output of second call is always 0. So I Thinked I've set first to NULL in somewhere in code; but I checked out all of methods and there was nothing like that. In addition, printed value is not the pointer itself; it's pointer's Data. Somewhere somebody changes Datas of all Node<T>*s in my list.
Is this a memory management or garbage collection issue? if not, what I'm doing wrong?
One thing that stands out here is that your signature is:
std::ostream& operator<<(std::ostream& out, const LinkedList1 item)
Instead of:
std::ostream& operator<<(std::ostream& out, const LinkedList1& item)
So, you are invoking a copy of your LinkedList. I suspect the issue here is that you have not correctly implemented your copy and assignment operators for LinkedList1, such that the the copy references the original content, and the destructor is making the original object into garbage.
I would recommend adding the following to your definition of LinkedList1:
private:
// The following declarations disallow copy and assignment. Do not implement.
LinkedList1(const LinkedList1&);
LinkedList1& operator=(const LinkedList1&);
Adding the above will lead to linker errors for the original signature that you had. I would then recommend passing the linked list by const reference, and your problem should disappear.
As an aside, I notice that many of your functions can be made const but aren't. For example, you have int Size() instead of int Size()const. One should generally mark as const anything that can be so-marked. This is known as "const-correctness" and can avoid a large number of issues.
Also, minor style nitpick: you have if...else statements where one has braces and the other doesn't. I would strongly recommend that you use braces in all cases as this leads to more readable code.