I'm trying to create a basic singly-linked list using a separate Node class and LinkedList class. I barely know what I'm doing as I've just started learning C++, so any help would be greatly appreciated.
The LinkedList part of the code runs on its own, but I'm sure there are some corrections to be made there too. My main problem is that, when trying to add to the linked list, I'm getting (at line 64 of LinkedList.h):
Exception thrown: read access violation. this->head was nullptr.
I'm using Microsoft Visual Studio 2015. Here's the code:
LinkedList.h (it's inline):
#pragma once
#include <iostream>
using namespace std;
class Node
{
private:
Node *next = NULL;
int data;
public:
Node(int newData) {
data = newData;
next = NULL;
}
Node() {
}
~Node() {
if(next)
delete(next);
}
Node(int newData, Node newNext) {
data = newData;
*next = newNext;
}
void setNext(Node newNext) {
*next = newNext;
}
Node getNext() {
return *next;
}
int getData() {
return data;
}
};
class LinkedList
{
private:
Node *head;
int size;
public:
LinkedList()
{
head = NULL;
size = 0;
}
~LinkedList()
{
}
void add(int numberToAdd)
{
head = new Node(numberToAdd, *head);
++size;
}
int remove()
{
if (size == 0) {
return 0;
}
else {
*head = (*head).getNext();
--size;
return 1;
}
}
int remove(int numberToRemove)
{
if (size == 0)
return 0;
Node *currentNode = head;
for (int i = 0; i < size; i++) {
if ((*currentNode).getData() == numberToRemove) {
*currentNode = (*currentNode).getNext();
return 1;
}
}
}
void print()
{
if (size == 0) {
return;
}
else {
Node currentNode = *head;
for (int i = 0; i < size; i++) {
cout << currentNode.getData();
currentNode = currentNode.getNext();
}
cout << endl;
}
}
};
List Tester.cpp
// List Tester.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main()
{
LinkedList myList;
myList.add(4);
system("pause");
}
You are making copies where you should not:
This:
Node(int newData, Node newNext) {
data = newData;
*next = newNext;
}
should be:
Node(int newData, Node* newNext) {
data = newData;
next = newNext;
}
Because now this:
head = new Node(numberToAdd, *head);
becomes this:
head = new Node(numberToAdd, head);
and will work even if head is a null pointer. You may need to adjust your other code accordingly.
Your whole implementation is full of errors. It should look more like this instead:
#pragma once
#include <iostream>
class Node
{
private:
int data;
Node *next;
public:
Node(int newData, Node *newNext = NULL)
: data(newData), next(newNext)
{}
void setNext(Node *newNext) {
next = newNext;
}
Node* getNext() {
return next;
}
int getData() {
return data;
}
};
class LinkedList
{
private:
Node *head;
int size;
public:
LinkedList()
: head(NULL), size(0)
{
}
~LinkedList()
{
Node *currentNode = head;
while (currentNode)
{
Node *nextNode = currentNode->getNext();
delete currentNode;
currentNode = nextNode;
}
}
void add(int numberToAdd)
{
head = new Node(numberToAdd, head);
++size;
}
bool remove()
{
Node *currentNode = head;
if (!currentNode)
return false;
head = currentNode->getNext();
delete currentNode;
--size;
return true;
}
bool remove(int numberToRemove)
{
Node *currentNode = head;
Node *previousNode = NULL;
while (currentNode)
{
if (currentNode->getData() == numberToRemove)
{
if (head == currentNode)
head = currentNode->getNext();
if (previousNode)
previousNode->setNext(currentNode->getNext());
delete currentNode;
return true;
}
previousNode = currentNode;
currentNode = currentNode->getNext();
}
return false;
}
void print()
{
Node *currentNode = head;
if (!currentNode) return;
do
{
std::cout << currentNode->getData();
currentNode = currentNode->getNext();
}
while (currentNode);
std::cout << std::endl;
}
};
Which can then be simplified using the std::forward_list class (if you are using C++11 or later):
#pragma once
#include <iostream>
#include <forward_list>
#include <algorithm>
class LinkedList
{
private:
std::forward_list<int> list;
public:
void add(int numberToAdd)
{
list.push_front(numberToAdd);
}
bool remove()
{
if (!list.empty())
{
list.pop_front();
return true;
}
return false;
}
bool remove(int numberToRemove)
{
std::forward_list<int>::iterator iter = list.begin();
std::forward_list<int>::iterator previous = list.before_begin();
while (iter != list.end())
{
if (*iter == numberToRemove)
{
list.erase_after(previous);
return true;
}
++previous;
++iter;
}
return false;
}
void print()
{
if (list.empty()) return;
std::for_each(list.cbegin(), list.cend(), [](int data){ std::cout << data });
std::cout << std::endl;
}
};
Related
I'm trying to implement a function in my linked list that pushes the values of one list into a stack, and then pops off those values into another list.
The problem is, when I try to std::cout << x, the first stack's topmost element, I get this error:
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\ostream:682:5: error: no type named 'type' in 'struct std::enable_if<false, std::basic_ostream<char>&>'
#include <iostream>
#include <cstddef>
#include <string>
#include <stack>
#include <vector>
using Item = std::string;
class List {
public:
class ListNode { //Changed this to public so I could access it. If this was in private how would I accomplish this?
public:
Item item;
ListNode * next;
ListNode(Item i, ListNode *n=nullptr) {
item = i;
next = n;
}
};
ListNode * head;
ListNode * tail; //Also in private, changed to public, so I could access it. This is the bottom boundry.
class iterator {
ListNode *node;
public:
iterator(ListNode *n = nullptr) {
node = n;
}
Item& getItem() { return node->item; }
void next() { node = node->next; }
bool end() { return node==nullptr; }
friend class List;
};
public:
List() {
// list is empty
head = nullptr;
tail = nullptr;
}
List(const List &other)
{
iterator o = other.begin();
while(!o.end())
{
append(o.getItem());
o.next();
}
}
bool empty() {
return head==nullptr;
}
// Only declared, here, implemented
// in List.cpp
void append(Item a);
bool remove (Item ©);
void insertAfter(iterator, Item);
void removeAfter(iterator, Item&);
iterator begin() const {
return iterator(head);
}
};
void List::append(Item a) {
ListNode *node = new ListNode(a);
if ( head == nullptr ) {
// empty list
head = node;
tail = node;
} else {
tail->next = node;
tail = node;
}
}
bool List::remove(Item ©)
{
if (!empty()) {
copy = head->item;
ListNode *tmp = head->next;
delete head;
head = tmp;
if (head==nullptr)
tail = nullptr;
return true;
}
return false;
}
void List::insertAfter(iterator it, Item item)
{
if (it.node == nullptr)
{
// insert at head
ListNode *tmp = new ListNode(item,head);
// if list is empty, set tail to new node
if (tail==nullptr) {
tail = tmp;
}
// set head to new node
head = tmp;
}
else
{
ListNode *tmp = new ListNode(item,it.node->next);
it.node->next = tmp;
// could be a new tail, if so update tail
if (tail==it.node) {
tail = tmp;
}
}
}
void List::removeAfter(iterator it, Item& item)
{
// emtpy list or at tail, just return
if (it.node == tail) return;
if (it.node == nullptr)
{
ListNode * tmp = head;
head = head->next;
delete tmp;
if (head==nullptr)
tail = nullptr;
}
else
{
ListNode *tmp = it.node->next;
it.node->next = tmp->next;
delete tmp;
// could be that it.node is the new nullptr
if (it.node->next == nullptr)
tail = it.node;
}
}
List reverse(const List &l)
{
List::iterator iter1 = l.begin();
std::stack<List::ListNode> first;
while(!(iter1.end())) {
first.push(iter1.getItem());
iter1.next();
}
List lthe3;
int z = first.size();
for (int i=0; i < z; ++i) {
List::ListNode x = first.top();
std::cout << x;
}
return l;
}
void printList(List &l) {
List::iterator i = l.begin();
while(!i.end()) {
std::cout << i.getItem() << ", ";
i.next();
}
std::cout << std::endl;
}
int main()
{
List l;
l.append("one");
l.append("two");
l.append("three");
l.append("four");
std::cout << "List in order: ";
printList(l);
List l2 = reverse(l);
std::cout << "List in reverse order: ";
printList(l2);
return 0;
}
I have no clue what I'm doing wrong, but I'm really close to finishing this function.
Is there any way I could get some feedback?
I am trying to implement the a dot product calculation formula into the linked list implementation on my below code and I am having the below error:
request for member 'add_node' in 'B', which is of pointer type 'linked_list {aka node*}' (maybe you meant to use '->' ?)
How can I clear that and make working code? I don't want to use classes as well
#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
typedef node* linked_list;
node *head = NULL;
node *tail = NULL;
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
int product=0;
while(A!=0 && B!=0)
{
if(A->index == B->index)
{
product = product + A->data * B->data;
A=A->next;
B=B->next;
}
else if(A->index < B->index)
{
A=A->next;
}
else
{
B=B->next;
}
}
return product;
return 0;
}
The error tells you what you need to know. linked_list is a pointer. You need to use the -> operator, not the dot operator.
Additionally, your node struct does not contain a method called add_node(). In fact it doesn't contain any methods at all.
#include <iostream>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
};
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
display(A.gethead());
display(B.gethead());
int product=0;
node *current_a = A.gethead();
node *current_b = B.gethead();
while(current_a != 0 && current_b!=0)
{
if(current_a->index == current_b->index)
{
product = product + current_a->data * current_b->data;
current_a=current_a->next;
current_b=current_b->next;
}
else if(current_a->index < current_b->index)
{
current_a=current_a->next;
}
else
{
current_b=current_b->next;
}
}
cout<<"\nDot Product : "<< product<<endl;
return 0;
}
enter code here
Today i'm praticing deleting a node implementation in LinkedList and this problem occur. This is my LinkedList.h file:
#pragma once
template <class Data>
class Node
{
public:
Node();
Node(Data newData, Node<Data>* newNext);
~Node();
Node<Data>* next;
Data data;
};
template<class Data>
class LinkedList
{
public:
LinkedList();
~LinkedList();
int size();
bool put(Data data,int pos);
bool del(int pos);
void show();
private:
typedef Node<Data>* nodePtr;
nodePtr head;
int N;
bool isEmpty();
nodePtr getPosition(int pos);
};
Then my LinkedList.cpp file:
#include <iostream>
#include "LinkedList.h"
using namespace std;
template<class Data>
Node<Data>::Node() {
next = NULL;
}
template<class Data>
Node<Data>::Node(Data newData, Node * newNext)
{
data = newData;
next = newNext;
}
template<class Data>
Node<Data>::~Node()
{
delete next;
}
template<class Data>
LinkedList<Data>::LinkedList() {
head = NULL;
N = 0;
}
template<class Data>
LinkedList<Data>::~LinkedList()
{
delete head;
}
template<class Data>
int LinkedList<Data>::size()
{
return N;
}
template<class Data>
bool LinkedList<Data>::isEmpty()
{
return N == 0;
}
template<class Data>
Node<Data>* LinkedList<Data>::getPosition(int pos)
{
nodePtr temp = head;
if (pos > N-1) pos = N-1;
for (int i = 0; i < pos; i++)
temp = temp->next;
return temp;
}
template<class Data>
bool LinkedList<Data>::put(Data data, int pos)
{
nodePtr add;
if (pos == 0) {
add = new Node<Data>(data, head);
head = add;
}
else{
nodePtr pPre = getPosition(pos-1);
nodePtr pCur = pPre->next;
add = new Node<Data>(data, pCur);
pPre->next = add;
}
N++;
return true;
}
template<class Data>
bool LinkedList<Data>::del(int pos)
{
if (isEmpty()) return false;
if (pos == 0) {
nodePtr pTemp = head;
head = head->next;
delete pTemp; //error
}
else {
nodePtr pPre = getPosition(pos - 1);
nodePtr pCur = pPre->next;
pPre->next = pCur->next;
delete pCur; //error
}
N--;
return true;
}
template<class Data>
void LinkedList<Data>::show()
{
for (nodePtr pTemp = head; pTemp != NULL; pTemp = pTemp->next)
cout << pTemp->data;
}
void main() {
LinkedList<int> list;
list.put(0, 0);
list.put(1, 0);
list.put(2, 0);
list.put(3, 0);
list.put(4, 0);
list.del(0);
list.show();
}
the program works if i comment these line (but i think it'll lead to memory leak), if i let these line there it cause "program has stopped working" and a random number in console window.
So can you guys please help me how to delete these pointer in correctly way?
Sorry for previous ambiguous question.
Sorry for my bad English.
Oh i just firgure out my mistake. Because of my ~Node() method here:
template<class Data>
Node<Data>::~Node()
{
delete next;
}
so when i delete a Node, it delete all pointer it linked to in a row, causing that error. Anyway thanks for helping guys.
I am using c++ to implement a single link list of integers. My program simply asks the user to fill the list with 5 integers, the program should then delete any even integer and print the list after deletion.
Here is my code:
#include <iostream>
using namespace std;
class IntSLLNode
{
public:
IntSLLNode() { next = 0; }
IntSLLNode(int i, IntSLLNode *ptr = 0)
{
info = i;
next = ptr;
}
int info;
IntSLLNode *next;
};
class IntSLList
{
public:
IntSLList() {head = tail =0; }
void AddToTail(int);
void DeleteNode(int);
void DisplayList();
void deleteEven();
IntSLLNode * getHead()
{
return head;
}
private:
IntSLLNode *head, *tail;
};
void IntSLList::AddToTail(int el)
{
if (tail != 0) // if list not empty;
{ tail->next = new IntSLLNode(el);
tail = tail->next;
}
else
head = tail = new IntSLLNode(el);
}
void IntSLList::deleteEven()
{
IntSLLNode *current;
current=head;
int num;
while (current!=0)
{
num=current->info;
current=current->next;
if(num%2==0)
{
DeleteNode(num);
}
}
}
void IntSLList::DeleteNode(int el)
{
if(head !=0)
if(head==tail && el==head->info)
{
delete head;
head=tail=0;
}
else if(el==head->info)
{
IntSLLNode *tmp=head;
head=head->next;
delete tmp;
}
else
{
IntSLLNode *pred, *tmp;
for(pred=head, tmp=head->next;
tmp!=0 && !(tmp->info==el);
pred=pred->next, tmp=tmp->next);
if(tmp!=0)
{
pred->next=tmp->next;
if(tmp==tail)
tail=pred;
delete tmp;
}
}
}
void IntSLList::DisplayList()
{
IntSLLNode *current;
current=head;
if(current==0)
cout<<"Empty List!";
while (current!=0)
{
cout<<current->info<<" ";
current=current->next;
}
}
I got Unhandled exception at 0x002c1744 in ex4.exe: 0xC0000005: Access violation reading location 0xfeeefeee in statment int num=current->info; Can anyone suggest how to solve this?
I'm not sure about this, but I think the problem is laid here:
void IntSLList::deleteEven()
{
IntSLLNode *current;
current=head;
while (current!=0)
{
if(current->info%2==0)
DeleteNode(current->info);
current=current->next; // this line
}
}
I think there is a relation between deleted node which is preformed in the if statement and your next line. If you delete that specific pointer which points to an element in DeleteNode() then your current which it might be deleted till now will be pointing to a wrong address.
EDIT
void IntSLList::deleteEven()
{
IntSLLNode *current;
current=head;
while (current!=0)
{
if(current->info%2==0)
{
int ind = current->info;
current=current->next;
DeleteNode(ind);
}
else
{
current=current->next;
}
}
}
I was writing a C++ program to implement a linked list. On compilation it's not giving any error but in the output windows it goes blank and program ended with
list1.exe has
encountered a problem and needs to close.
Debugger response: Program received signal SIGSEGV, Segmentation fault.
Maybe it's because of memory leakage, but I'm not able to figure out the exact bug and how can we fix that. Please what's wrong in the prog and what should be fixed?
Below is the code
//Program to implement linked list
#include <iostream>
#include <cstdlib>
using namespace std;
class Node
{
int data;
Node * next;
public:
Node (){}
int getdata(){return data ;}
void setdata(int a){data=a;}
void setnext(Node* c){next=c;}
Node* getnext(){return next;}
};
class linkedlist
{
Node* head;
public:
linkedlist(){head=NULL;}
void print ();
void push_back(int data);
};
void linkedlist::push_back(int data)
{
Node* newnode= new Node();
if(newnode!=NULL)
{
newnode->setdata(data);
newnode->setnext(NULL);
}
Node* ptr= head;
if(ptr==NULL)
{head=newnode;}
while ((ptr->getnext())!=NULL)
{
ptr=ptr->getnext();
}
ptr->setnext(newnode);
}
void linkedlist::print()
{
Node* ptr=head;
if(ptr==NULL)
{cout<<"null"; return;}
while(ptr!=NULL)
{
cout<<(ptr->getdata())<<" ";
ptr=ptr->getnext();
}
}
int main()
{
linkedlist list;
list.push_back(30);
list.push_back(35);
list.print();
return 0;
}
The main issue is here:
if(ptr==NULL) {head=newnode;}
while ((ptr->getnext())!=NULL)
{
ptr=ptr->getnext();
}
ptr->setnext(newnode);
There's probably meant to be a return; in the if (ptr == NULL) part; as it stands, it sets head = newnode, but then continues to try to access ptr->getnext(), which causes the segfault.
Some answers have suggested setting ptr = head = newnode, but note that the bottom line is ptr->setnext(newnode)—this would cause head->getnext() == head. Infinite list!
For your interest, here's your code:
Formatted nice;
Cleaned up not to use using namespace std; (see the C++ FAQ on this);
Takes advantage of const-correctness;
etc.
Enjoy!
#include <iostream>
#include <stdexcept>
class Node {
int data;
Node *next;
public:
Node(): next(NULL) {}
int getdata() const {
return data;
}
void setdata(int a) {
data = a;
}
Node *getnext() const {
return next;
}
void setnext(Node *c) {
next = c;
}
};
class linkedlist {
Node* head;
public:
linkedlist(): head(NULL) {}
void print() const {
Node *ptr = head;
if (ptr == NULL) {
std::cout << "null";
return;
}
while (ptr != NULL) {
std::cout << ptr->getdata() << " ";
ptr = ptr->getnext();
}
}
void push_back(int data) {
Node *newnode = new Node();
if (newnode == NULL) {
throw std::runtime_error("out of memory!");
}
newnode->setdata(data);
Node *ptr = head;
if (ptr == NULL) {
head = newnode;
return;
}
while ((ptr->getnext()) != NULL) {
ptr = ptr->getnext();
}
ptr->setnext(newnode);
}
};
int main() {
linkedlist list;
list.push_back(30);
list.push_back(35);
list.print();
return 0;
}
In the following line: while ((ptr->getnext())!=NULL) ptr is NULL
The push_back code is incorrect, and I've seen some other parts of your code that can be improved:
#include <iostream>
#include<cstdlib>
using namespace std;
class Node
{
int data;
Node * next;
public:
Node(int d = 0) : data(d), next(NULL) {}
int getdata() { return data; }
void setdata(int a) { data = a; }
void setnext(Node* c) { next = c; }
Node* getnext() { return next; }
};
class linkedlist
{
Node* head;
public:
linkedlist() : head(NULL) {}
void print ();
void push_back(int data);
};
void linkedlist::push_back(int data)
{
Node* newnode = new Node(data);
if(head == NULL)
{
head = newnode;
}
else
{
Node* last = head;
while(last->getnext() != NULL)
last = last->getnext();
last->setnext(newnode);
}
}
void linkedlist::print()
{
Node* ptr = head;
if(!ptr)
{
cout << "null";
return;
}
while(ptr != NULL)
{
cout << ptr->getdata() << " ";
ptr=ptr->getnext();
}
}
int main()
{
linkedlist list;
list.push_back(30);
list.push_back(35);
list.print();
return 0;
}
There are still some points to be improved...