I can't specify what the problem is nor do I get any errors. This is my code:
Node.h:
#ifndef NODE_H
#define NODE_H
#include <iostream>
using namespace std;
template <typename T>
class LinkedList;
template <typename T>
class Node {
public:
Node(T data) : data(data),previousNode(nullptr),nextNode(nullptr) {}
Node<T>* GetNextNode() const {
return nextNode;
}
void SetNextNode(Node<T>* nextNode) {
this->nextNode = nextNode;
}
Node<T>* GetPreviousNode() const {
return previousNode;
}
void SetPreviousNode(Node<T>* previousNode) {
this->previousNode = previousNode;
}
T GetData() const {
return data;
}
void SetData(T data) {
this->data = data;
}
private:
T data;
Node<T>* previousNode;
Node<T>* nextNode;
};
#endif /* NODE_H */
linkedList.h:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "node.h"
#include <stdexcept>
#include <iostream>
#include <booking.h>
using namespace std;
template<typename T>
class LinkedList {
public:
LinkedList() {
root = nullptr;
end = nullptr;
cursor = end;
}
void insertNode(T data) {
Node<T>* node = new Node<T>(data);
cerr << "entered insert node" << endl;
if (root == nullptr) {
root = node;
node->SetNextNode(end);
end->SetPreviousNode(node);
}else{
node->SetNextNode(cursor);
node->SetPreviousNode(cursor->GetPreviousNode());
if (cursor->GetPreviousNode())
cursor->GetPreviousNode()->SetNextNode(node);
cursor->SetPreviousNode(node);
}
cursor = node;
if (!cursor->GetPreviousNode())
root = cursor;
}
bool isAtEnd() {
return (cursor == end);
};
void step_back() {
if (cursor && cursor->GetPreviousNode()) {
cursor = cursor->GetPreviousNode();
}
}
void advance() {
if (cursor && cursor->GetNextNode()) {
cursor = cursor->GetNextNode(); }
};
T getNode() {
return cursor->GetData();
};
void reset() {
cursor = root;
};
void deleteNode() {
Node<T>* tmpPrevious;
Node<T>* tmpNext;
if (root == nullptr) {
throw underflow_error("empty list...");
} else {
if (cursor->GetPreviousNode() == nullptr) {
if (cursor->GetNextNode() == end) {
delete cursor;
root = nullptr;
end->SetPreviousNode(nullptr);
cursor = end;
} else {
cursor = cursor->GetNextNode();
delete (root);
cursor->SetPreviousNode(nullptr);
root = cursor;
}
} else {
if (cursor->GetNextNode() == end) {
tmpPrevious = cursor->GetPreviousNode();
delete cursor;
cursor = end;
end->SetPreviousNode(tmpPrevious);
tmpPrevious->SetNextNode(end);
} else {
tmpPrevious = cursor->GetPreviousNode();
tmpNext = cursor->GetNextNode();
delete cursor;
tmpPrevious->SetNextNode(tmpNext);
tmpNext->SetPreviousNode(tmpPrevious);
cursor = tmpNext;
}
}
}
return;
};
protected:
Node<T>* root;
Node<T>* cursor;
Node<T>* end;
};
#endif /* LINKEDLIST_H */
Booking.h
#ifndef BOOKING_H
#define BOOKING_H
class Booking{
private:
long bookingID;
public:
Booking(long bookingID);
long getBookingID();
};
#endif // BOOKING_H
Booking.ccp:
#include "booking.h"
Booking::Booking(long bookingID):bookingID(bookingID){}
long Booking::getBookingID(){
return bookingID;
}
main.cpp:
#include <QCoreApplication>
#include <cstdlib>
#include <linkedList.h>
#include <iostream>
#include <string>
#include <booking.h>
using namespace std;
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
LinkedList<Booking*> allBookings;
Booking* booking1 = new Booking(12);
allBookings.insertNode(booking1);
long test = allBookings.getNode()->getBookingID();
cout << "test: " << test << endl; //doesn't print anything
return a.exec();
}
I didn't get any errors. cout << "test: " << test << endl; in the main.cpp doesn't execute, because I was expecting it to print something. What am I doing wrong here? I did some debugging and I think in my Node.h implementation the function SetPreviousNode doesn't execute when I'm trying to insert a node in the main.cpp.
This code in insertNode
if (root == nullptr) {
root = node;
node->SetNextNode(end);
end->SetPreviousNode(node);
}else{
end has a value of nullptr at when you reach end->SetPreviousNode(node); which is likely crashing your program. (You should be able to confirm that in your debugger).
I'd like to suggest a fix but it's not clear to me what you are trying to do. The code seems a little complex. Plus I don't like the design decision to include a cursor in the list. I would drop that if you are able to.
Related
Reading from a file, each line is stored in a list as an individual row. Each row contains two standard values and a variable amount stored in a list. Therefore each node has two values and a list. Initialization through operator>> works, but as soon as I try to run the loadfile function it crashes with the error: free(): double free detected in tcache 2 Aborted (core dumped)
Here is the code
#include <iostream>
#include "Resource.h"
#include "list.h"
#include "node.h"
using std::cout;
using rows = List<Resource>;
using row = Node<Resource>;
void loadFile(string idata, rows &res)
{
ifstream ifs(idata, ifstream::in);
while (ifs.good())
{
Resource s;
ifs >> s;
row *temp = new Node<Resource>(s);
res.insert(temp);
}
ifs.close();
}
int main()
{
rows resList;
loadFile("data.txt", resList);
cout << resList.getHead()->getValue();
}
this is the source for the class that stores the values, that will be wrapped in a Node template class.
#ifndef RESOURCE_H
#define RESOURCE_H
#include <iostream>
#include <fstream>
#include <string>
#include "list.h"
#include "node.h"
#include <stdio.h>
#include <algorithm>
using std::cout;
using std::istream;
using std::string;
class Resource
{
private:
string Name;
int amt;
List<string> clientList;
public:
Resource(string n, int a) : Name(n), amt(a) {}
Resource(string n) : Resource(n, 0) {}
Resource() : Resource("", 0) {}
string getName()
{
return this->Name;
}
int getAmt()
{
return this->amt;
}
void setName(string n)
{
this->Name = n;
}
void setAmt(int a)
{
this->amt = a;
}
friend ostream &operator<<(ostream &out, const Resource &r)
{
out << r.Name << ";" << r.amt;
List<string> temp = r.clientList;
for (Node<string> *app = temp.getHead(); app != NULL; app = app->getNext())
{
out << ';';
out << app->getValue();
}
return out;
}
friend istream &operator>>(istream &in, Resource &r)
{
string Name;
string amt;
string params;
string tempVar;
getline(in, Name, ';');
getline(in, amt, ';');
getline(in, params, '\n');
const int paramsOriginalLength = count(params.begin(), params.end(), ';');
for (int i = 0; i < paramsOriginalLength; i++)
{
r.clientList.insert(params.substr(0, params.find(';')));
params.erase(0, params.find(';') + 1);
}
r.setName(Name);
r.setAmt(stoi(amt));
return in;
}
};
#endif
EDIT: Since the problem might be caused by the data structure's defintion I will include the source of list.h and node.h
List:
#ifndef LIST_H
#define LIST_H
// Standard Template Linked List - List - by Eduardo Meli - 2020
#include "node.h"
#include <iostream>
using namespace std;
template <class T>
class List
{
private:
int length;
Node<T> *head;
public:
List(int length, Node<T> *head) : length(length), head(head) {}
List() : List(0, NULL) {}
Node<T> *getHead()
{
return this->head;
}
int getLength()
{
return this->length;
}
void insert(T value)
{
Node<T> *app = new Node<T>(value);
this->insert(app);
}
void insert(Node<T> *n)
{
if (head == NULL)
{
head = n;
length++;
return;
}
Node<T> *curr = head;
while (curr->getNext() != NULL)
{
curr = curr->getNext();
}
curr->setNext(n);
length++;
}
void deleteNode(Node<T> *n)
{
if (n == this->getHead())
{
this->head = head->getNext();
this->length = length - 1;
delete n;
return;
}
Node<T> *prev = head;
Node<T> *curr = head->getNext();
while (curr != NULL)
{
if (curr == n)
{
prev->setNext(curr->getNext());
length--;
return;
}
prev = curr;
curr = curr->getNext();
}
}
Node<T> *deleteNode(T value)
{
if (this->seekNode(value))
{
if (head->getValue() == value)
{
Node<T> *temp = head;
head = head->getNext();
length--;
return temp;
}
Node<T> *prev = head;
Node<T> *curr = head->getNext();
while (curr != NULL)
{
if (curr->getValue() == value)
{
prev->setNext(curr->getNext());
length--;
return curr;
}
prev = curr;
curr = curr->getNext();
}
}
return NULL;
}
void print()
{
Node<T> *nk = this->getHead();
while (nk != NULL)
{
cout << nk->getValue() << endl;
nk = nk->getNext();
}
}
~List()
{
Node<T> *ptr;
for (ptr = head; head; ptr = head)
{
head = head->getNext();
delete ptr;
}
}
};
#endif
And node:
#ifndef NODE_H
#define NODE_H
// Standard Template Linked List - Node - by Eduardo Meli - 2020
#include <fstream>
#include <iostream>
using namespace std;
template <class T>
class Node
{
private:
T value;
Node<T> *next;
public:
Node(T value, Node<T> *next) : value(value), next(next) {}
Node(T value) : Node(value, NULL) {}
Node() : Node(0, NULL) {}
T getValue()
{
return this->value;
}
Node<T> *getNext()
{
return this->next;
}
void setValue(T val)
{
this->value = val;
}
void setNext(Node<T> *n)
{
this->next = n;
}
friend ostream &operator<<(ostream &out, const Node &n)
{
out << n.value;
return out;
}
};
#endif
I am implementing a template sorted linked list with sorted insert. I also made the class Booking. Booking is a base class and derived from it are some bookingtypes. I want to use the linked list to store some Booking*s in there. (I have to use pointers here)
Bookings.h
#ifndef BOOKING_H
#define BOOKING_H
#include <iostream>
class Booking{
private:
long bookingID;
public:
Booking(long bookingID);
long getBookingID();
bool operator<(Booking& b1);
};
#endif // BOOKING_H
Booking.cpp (the < operator is being overloaded here)
#include "booking.h"
Booking::Booking(long bookingID):bookingID(bookingID){}
long Booking::getBookingID(){
return bookingID;
}
bool Booking::operator<(Booking &b){
return this->bookingID < b.getBookingID();
}
node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
using namespace std;
template <typename T>
class LinkedList;
template <typename T>
class Node {
public:
Node(T data) : data(data),previousNode(nullptr),nextNode(nullptr) {}
Node<T>* GetNextNode() const {
return nextNode;
}
void SetNextNode(Node<T>* nextNode) {
this->nextNode = nextNode;
}
Node<T>* GetPreviousNode() const {
return previousNode;
}
void SetPreviousNode(Node<T>* previousNode) {
this->previousNode = previousNode;
}
T GetData() const {
return data;
}
void SetData(T data) {
this->data = data;
}
private:
T data;
Node<T>* previousNode;
Node<T>* nextNode;
};
#endif /* NODE_H */
linkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "node.h"
#include <stdexcept>
#include <iostream>
#include <booking.h>
using namespace std;
template<typename T>
class LinkedList {
public:
LinkedList(T data) {
root = nullptr; // root darf nur bei einer leeren Liste gleich NULL sein
end = new Node<T>(data);
cursor = end;
}
bool isAtEnd() {
return (cursor == end);
};
void step_back() {
if (cursor && cursor->GetPreviousNode()) {
cursor = cursor->GetPreviousNode();
}
}
void advance() {
if (cursor && cursor->GetNextNode()) {
cursor = cursor->GetNextNode(); }
};
T getNode() {
return cursor->GetData();
};
void reset() {
cursor = root;
};
void sortedInsert(T data) {
Node<T>* node = new Node<T>(data);
reset();
if(root == nullptr){
root = node;
node->SetNextNode(end);
end->SetPreviousNode(node);
cursor = node;
root = cursor;
}else{
while(!isAtEnd()){
if((*data<*(cursor->GetData()))){
node->SetPreviousNode(cursor->GetPreviousNode());
node->SetNextNode(cursor);
cursor->GetPreviousNode()->SetNextNode(node);
cursor->SetPreviousNode(node);
reset(); //cursor zurück zu listenanfang (root)
return;
}
advance();
}
if(!isAtEnd()){
node->SetPreviousNode(end->GetPreviousNode());
node->SetNextNode(end);
end->GetPreviousNode()->SetNextNode(node);
end->SetPreviousNode(node);
}
}
reset();
}
protected:
Node<T>* root;
Node<T>* cursor;
Node<T>* end;
};
#endif /* LINKEDLIST_H */
main.cpp
#include <QCoreApplication>
#include <cstdlib>
#include <linkedList.h>
#include <iostream>
#include <string>
#include <booking.h>
using namespace std;
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
// creating a linked list with dummy node at the end.
LinkedList<Booking*> allBookings = LinkedList<Booking*>(new Booking(-1));
// these bookings are in actual some bookingtypes stored in Booking
// for example: Booking* bookingx = new FlightBooking(12);
Booking* booking1 = new Booking(99);
Booking* booking2 = new Booking(11);
Booking* booking3 = new Booking(12);
Booking* booking4 = new Booking(33);
Booking* booking5 = new Booking(5);
Booking* booking6 = new Booking(45);
Booking* booking7 = new Booking(34);
allBookings.sortedInsert(booking1);
allBookings.sortedInsert(booking2);
allBookings.sortedInsert(booking3);
allBookings.sortedInsert(booking4);
allBookings.sortedInsert(booking5);
allBookings.sortedInsert(booking6);
allBookings.sortedInsert(booking7);
return a.exec();
}
I am guessing that my sortedInsert(...) function doesn't work, because the overloading isn't working like expected. I need help in fixing my code.
So far I have created a simple linked list project that I will build on in the future. All files compile correctly but when I try to build my project it comes up with a link error. I used an empty project to start. The main.cpp is used to demo that my linked list actually works. I'm really stuck and don't know how to solve this issue.
Main.cpp
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include "LinkedList.cpp"
#include "LinkedList.h"
using namespace SDI;
template <class T>
int LinkedList<T>::main()
{
LinkedList<T> menu;
menu.insert(1);
menu.insert(4);
menu.insert(7);
menu.insert(2);
menu.insert(8);
menu.display();
Std::cout << "-----" << endl;
menu.remove(2);
menu.remove(1);
menu.remove(10);
menu.display();
return 0;
};
header file LinkedList.h
#ifndef SDI_LL
#define SDI_LL
namespace SDI
{
template < class T >
class LinkedList
{
class Node
{
int number;
Node* next;
};
private:
T head;
T current;
T temp;
public:
LinkedList();
~LinkedList();
int main();
void insert(int add);
void remove(int remove);
void display();
};
}
#endif
LinkedList.cpp
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <string>
#include "LinkedList.h"
using namespace SDI;
template <class T>
LinkedList<T>::LinkedList()
{
head = NULL;
current = NULL;
temp = NULL;
};
template <class T>
void LinkedList<T>::insert(int add)
{
newnode = new Node;
newnode->next = NULL;
newnode->number = add;
if (head != NULL)
{
current = head;
while (current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
else
{
head = newnode;
}
};
template <class T>
void LinkedList<T>::remove(int remove)
{
remove1 = NULL;
temp = head;
current = head;
while (current != NULL && current->add != remove)
{
temp = current;
current = current->next;
}
if (current == NULL)
{
std::cout << "N/A\n";
delete remove1;
}
else
{
remove1 = current;
current = current->next;
temp->next = current;
if (remove1 == head)
{
head = head->next;
temp = NULL;
}
delete remove1;
}
};
template <class T>
void LinkedList<T>::display()
{
current = head;
while (current != NULL)
{
std::cout << current->number;
current = current->next;
}
};
You need a global main() function in your program, not the static version from LinkedList. The main function is called the entry point, and a quick lookup of the error message tells you this.
http://en.cppreference.com/w/cpp/language/main_function
Something along the lines of this might work:
int main()
{
LinkedList<int> menu;
menu.insert(1);
menu.insert(4);
menu.insert(7);
menu.insert(2);
menu.insert(8);
menu.display();
Std::cout << "-----" << endl;
menu.remove(2);
menu.remove(1);
menu.remove(10);
menu.display();
return 0;
};
Currently, you define a completely unrelated "main" function inside your class. This is just a plain normal function of your class and in no way related to the previously mentioned int main() entry point function.
node.h:
#ifndef NODE_H
#define NODE_H
#include <iostream>
namespace mdm{
class node{
public:
typedef int value_type;
node(const value_type& init_data = value_type(), node *init_link = NULL){
data = init_data;
link = init_link;
}
void setData(const value_type& newData){
data = newData;
}
void setLink(node *newLink){
link = newLink;
}
value_type getdata() const {
return data;
}
const node *linker() const {
return link;
}
node *linker(){
return link;
}
private:
value_type data;
node *link;
};
}
#endif // !node_h
linked_list.h:
#ifndef linked_list_h
#define linked_list_h
#include <iostream>
#include "node.h"
namespace mdislamwork_at_gmail_com{
class llist{
public:
llist(node *head = NULL){
head_ptr = head;
}
size_t list_length(const node *head_ptr);
void insert(const node::value_type& entry, size_t position);
void remove(node del);
void insert_to_head(node *&head_ptr, const node::value_type &entry);
private:
node *head_ptr;
};
}
#endif // !linked_list.h
linked_list.cpp:
#include <iostream>
#include "linked_list.h"
#include <assert.h>
using namespace std;
namespace mdm{
size_t llist::list_length(const node *head_ptr){
const node *cursor;
size_t count = 0;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->linker()) {
count++;
}
return count;
}
void llist::insert(const node::value_type& entry, size_t position){
node* prev_ptr = head_ptr;
if (list_length(head_ptr) == 0)
insert_to_head(head_ptr, entry);
else{
assert(prev_ptr != NULL);
size_t count = 0;
while (count < position){
prev_ptr = prev_ptr->linker();
count++;
}
}
node *m_head_ptr;
assert(prev_ptr != NULL);
m_head_ptr = prev_ptr->linker();
insert_to_head(m_head_ptr, entry);
prev_ptr->setLink(m_head_ptr);
}
void llist::remove(node del){
}
void llist::insert_to_head(node *&head_ptr, const node::value_type &entry){
head_ptr = new node(entry, head_ptr);
}
}
main.cpp
#include <iostream>
#include "node.h"
#include "linked_list.h"
using namespace std;
using namespace mdm;
int main() {
node *head_ptr = NULL;
llist linked_list(head_ptr);
linked_list.insert_to_head(head_ptr, 44);
cout << linked_list.list_length(head_ptr) << endl;
linked_list.insert_to_head(head_ptr, 49);
cout << linked_list.list_length(head_ptr) << endl;
linked_list.insert(5,2);
//linked_list.insert(5, 2);
cout << linked_list.list_length(head_ptr) << endl;
return 0;
}
I posted the entirety of the code. I am having trouble inserting at an n-th position. For some reason in the insert implementation, the prev_ptr is NULL when it should have the memory address of where the new node will be placed.
Its hard to tell what the problem is what with head_ptr and its operations out of the scope of your posted method. What is head_ptr? A node*? a node? How are your nodes inserted initially? The scope of this method in relation to your problem is hard to understand.
Check to see if the head_ptr variable is null throughout the whole of your program. Is it always null? Does it become null? What other operations for your linked list have you implemented? Do they work ok? Its just really hard to tell what is wrong when you provide one method to an entire implementation.
I'm creating a program with multiple files and it's not recognizing cout<< in my tnode file. Can anyone locate where the problem is? Among other errors, I get this error "cout was not declared in this scope" in my node file.
My main function:
#include <iostream>
#include "bst.h"
using namespace std;
int main(int argc, char *argv[]) {
cout<<"hi";
bst *list = new bst();
return 0;
}
My BinarySearchTree file:
#ifndef bst_H
#define bst_H
#include <iostream>
#include <string>
#include "tnode.h"
class bst
{
public:
bst()
{
root = NULL;
}
void add(int key, char value) {
if (root == NULL) {
root = new tnode(key, value);
return
} else
root->add(key, value);
return
}
tnode *root;
};
#endif
My node file:
#ifndef tnode_H
#define tnode_H
#include <iostream>
#include <string>
class tnode
{
public:
tnode(int key, char value)
{
this->key = key;
this->value = value;
N = 1;
left = NULL;
right = NULL;
cout<<"hi";
}
void add(int key, char value) {
if (key == this->key)
{
cout<<"This key already exists";
return;
}
else if (key < this->key)
{
if (left == NULL)
{
left = new tnode(key, value);
cout<<"Your node has been placed!!";
return;
}
else
{
left->add(key, value);
cout<<"Your node has been placed!";
return;
}
}
else if (key > this->key)
{
if (right == NULL)
{
right = new tnode(key, value);
cout<<"Your node has been placed!!"; return;
}
else
return right->add(key, value);
}
return;
}
tnode* left;
tnode* right;
int key;
char value;
int N;
};
#endif
You need to do :
using namespace std;
or
std::cout
in your tnode file
But using namespace std is considered bad practice, so you'd better use the second way:
std::cout<<"Your node has been placed!!";
You need to use the namespace std. Either by using namespace std (which could go in .cpp files but never in .h files, read more about why here) or by using std::cout when calling it.