Implementing List and Stack manually with template - c++

my data structure teacher gave us the task to implement lists and stacks manually and it worked just fine, but then we had to reimplement it to accept any type of parameters using template. Since then, I've been facing lots of different errors. Right now, I'm having a c2019 error, but I can't see what's wrong with my code.
Tried this:pilha.getTopo<int>();, this: Lista<int> lista;, this: typedef Lista<int> Lista_int;, but no luck.
Now, my code:
######UPDATE: The code bellow is working
Listas.h
#pragma once
#include "stdafx.h"
#include <iostream>
using namespace std;
/*============================Node================================*/
template <typename N>
class Node
{
N value;
Node *next, *prev;
public:
Node(void) {};
Node(N _value){
this->value = _value;
this->prev = NULL;
this->next = NULL;
};
~Node(void) {};
void setValue(int _value) { this->value = _value; }
void setNext(Node *_next) { this->next = _next; }
void setPrev(Node *_prev) { this->previous = _prev; }
int getValue() { return this->value; }
Node *getNext() { return this->next; }
Node *getPrev() { return this->prev; }
};
/*===========================List===============================*/
template <typename T>
class List
{
Node<T> *begin, *end;
int list_size;
public:
List(void){
this->begin = NULL;
this->end = NULL;
this->list_size = 0;
};
~List(void) {};
template <typename T> void insertBegin(Node<T> node){
Node<T> *newNode = new Node<T>;
*newNode = node;
if(this->list_size == 0){
this->begin = this->end = newNode;
this->list_size += 1;
}else{
newNode->setNext(begin);
this->begin = newNode;
this->list_size += 1;
}
};
template <typename T> void removeBegin(Node<T> node){
Node<T> *newNode = new Node<T>;
*newNode = node;
if(this->list_size == 0){
this->begin = this->end = NULL;
this->list_size = 0;
}else{
if(begin == end)
this->end = NULL;
this->begin = newNode->getNext();
newNode = begin;
newNode->setPrev(NULL);
this->list_size -= 1;
}
};
template <typename T> void insertEnd(Node<T> node){
Node<T> *newNode = new Node<T>;
*newNode = node;
if(this->list_size == 0){
this->begin = this->end = newNode;
this->list_size += 1;
}else{
newNode->setPrev(end);
this->end = newNode;
this->list_size += 1;
}
};
template <typename T> void removeEnd(Node<T> node){
Node<T> *newNode = new Node<T>;
*newNode = node;
if(this->list_size == 0){
this->begin = this->end = NULL;
this->list_size = 0;
}else{
if(begin == end)
this->end = NULL;
this->end = newNode->getPrev();
newNode = end;
newNode->setNext(NULL);
this->list_size -= 1;
}
};
template <typename T> void exibeList(){
Node<T> *node;
cout << "Begin: " << begin << endl
<< "End: " << end << endl
<< "Size: " << list_size << endl << endl;
if(begin != NULL){
node = begin;
do{
cout << "Mem. adress: " << &node << endl
<< "Value: " << node->getValue() << endl
<< "Previous: " << node->getPrev() << endl
<< "Next: " << node->getNext() << endl
<< endl;
node = node->getNext();
}while(node != NULL);
}
};
};
/*===========================Stack==============================*/
template <typename T>
class MyStack
//: public List<T>
{
Node<T> *top, *next;
int my_stack_size;
public:
MyStack<T>(void){
this->my_stack_size = 0;
this->top = NULL;
this->next = NULL;
};
~MyStack<T>(void) {};
template <typename T> void insertTop(Node<T> node){
Node<T> *newNode = new Node<T>;
*newNode = node;
if(this->my_stack_size == 0){
this->top = this->next = newNode;
this->my_stack_size += 1;
}else{
newNode->setNext(top);
this->next = top;
this->top = newNode;
this->my_stack_size += 1;
}
};
template <typename T> void removeTop(){
Node<T> *node;
if(this->my_stack_size > 0){
node = top;
this->top = next;
delete node;
this->my_stack_size -= 1;
}else
cout << "Stack underflow." << endl;
};
template <typename T> void getTop(){
Node<T> *node = new Node<T>;
node = top;
if(node->getPrev() == NULL)
cout << node->getValue() << endl;
else
cout << "Error. Node isn't the first." << endl;
};
template <typename T> void show(){
Node<T> *node;
cout << "Top: " << top << endl
<< "Next: " << next << endl
<< "Size: " << my_stack_size << endl << endl;
if(top != NULL){
node = top;
do{
cout << "Mem. adress: " << &node << endl
<< "Value: " << node->getValue() << endl
<< "Previous: " << node->getPrev() << endl
<< "Next: " << node->getNext() << endl
<< endl;
node = node->getNext();
}while(node != NULL);
}
};
};
and finally, Lista.cpp
// Lista.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Listas.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
/* ERROR C2019
//typedef Pilha<int> Pilha_int;
//typedef Nodo<int> Nodo_int;
//
//Lista_int lista;
//Pilha_int pilha;
//Nodo_int nodo(25), nodo2(40), nodo3(55), nodo4(70);
*/
/* C2019
Pilha<int> pilha;
Nodo<int> nodo(25), nodo2(40);
/*error C2955: use of class template requires template argument list
//Pilha pilha;
//Nodo nodo(25), nodo2(40), nodo3(55), nodo4(70);
pilha.insereTopo(nodo);
pilha.getTopo(); //C2783
pilha.insereTopo(nodo2);
pilha.getTopo(); //C2783
pilha.exibe(); //error C2783: could not deduce template argument for 'T'
pilha.exibe<int>(); //C2019
system("pause");
return 0;
}
Thanks in advance.

Related

Why is the copy constructor being called twice? [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 2 years ago.
Improve this question
How come when I do Queue<listEntry<int> > queue2(intList); the copy constructor is being called twice?
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template <class dataType>
class listEntry
{
private:
dataType data;
public:
listEntry *next;
listEntry *prev;
dataType getData() { return this->data; }
listEntry();
listEntry(dataType data) { this->data = data; }
~listEntry() {};
};
template <class dataType>
class List
{
private:
dataType *head;
dataType *tail;
int count;
public:
dataType *getHead() { return this->head; }
dataType *getTail() { return this->tail; }
void addToTail(dataType *newEntry);
void addToHead(dataType *newEntry);
int getCount() { return count; }
void printListForward();
List();
List(const List<dataType> &li);
~List();
};
template <class dataType>
class Queue: public List<dataType>
{
public:
void enQueue(dataType *newEntry);
Queue():List<dataType>() { return; }
Queue(List<dataType> li):List<dataType>(li) { return; }
};
void addIntegersToList(Queue<listEntry<int> > *queue);
int main()
{
cout << "Queue of Integers: " << endl;
cout << "Default Queue Constructor: " << endl;
//Create an intance of a queue using the default queue constructor
Queue<listEntry<int> > queue;
addIntegersToList(&queue);
queue.printListForward();
cout << endl;
cout << "List parameter Queue Constructor: " << endl;
//Create a new list that will be used to initiate an instance of a queue
List<listEntry<int> > intList;
//Add some data to that list
intList.addToTail(new listEntry<int>(11));
//Now create a new instance of a queue with a list as its creation parameter
Queue<listEntry<int> > queue2(intList);
//addIntegersToList(&queue2);
//queue2.printListForward();
while (true);
}
template <class dataType>
List<dataType>::List()
{
this->head = NULL;
this->tail = NULL;
this->count = 0;
}
template <class dataType>
void List<dataType>::addToTail(dataType *newEntry)
{
newEntry->next = NULL;
newEntry->prev = NULL;
if (this->head == NULL)
{
this->head = newEntry;
this->tail = this->head;
this->count = this->count + 1;
}
else
{
this->tail->next = newEntry;
newEntry->prev = this->tail;
this->tail = newEntry;
this->count = this->count + 1;
}
dataType *temp = this->tail;
}
template <class dataType>
void List<dataType>::addToHead(dataType *newEntry)
{
newEntry->next = NULL;
newEntry->prev = NULL;
if (this->head == NULL)
{
this->head = newEntry;
this->tail = this->head;
}
else
{
this->head->prev = newEntry;
newEntry->next = this->head;
this->head = newEntry;
}
this->count = this->count + 1;
}
template <class dataType>
void List<dataType>::printListForward()
{
cout << "Head: ";
dataType *temp = this->head;
while (temp)
{
cout << temp->getData() << " -> ";
temp = temp->next;
}
cout << " :Tail" << endl;
}
void addIntegersToList(Queue<listEntry<int> > *queue)
{
int i = 0;
for (i = 1; i <= 10; i++)
queue->enQueue(new listEntry<int>(i));
}
template <class dataType>
void Queue<dataType>::enQueue(dataType *newEntry)
{
this->addToTail(newEntry);
}
template <class dataType>
List<dataType>::~List()
{
while (this->head)
{
dataType *next = this->head->next;
delete this->head;
this->count = this->count - 1;
this->head = next;
}
}
template <class dataType>
List<dataType>::List(const List<dataType> &li)
{
tail = new dataType;
*tail = *li.tail;
head = new dataType;
*head = *li.head;
cout << "head: " << head << endl;
cout << "tail: " << tail << endl;
count = li.count;
cout << "count: " << count << endl;
}
template <class dataType>
listEntry<dataType>::listEntry()
{
this->next = NULL;
this->prev = NULL;
this->data = 0;
}
Because you are passing the List by value to the Queue constructor. Try this instead
Queue(const List<dataType>& li):List<dataType>(li) { return; }

nullptr = Node is not assigning correctly

please don't dig into me too hard, I am still steadily learning and ran into an issue when trying to construct an AVL tree. When iterating through the tree on insert, I go until I reach a nullptr, create a new node, and assign that ptr to the nullptr. The value is never accepted though. Can someone find the error and explain it to me? ty!
#ifndef AVLTree_hpp
#define AVLTree_hpp
#include <stdio.h>
#include <stack>
template<typename T>
class AVLTree{
private:
struct Node{
T val;
Node* left;
Node* right;
int height;
Node(T V)
:left{nullptr},right{nullptr}
{
val = V;
}
~Node(){
}
};
Node* head;
void rightRotate(Node*& node);
void leftRotate(Node*& node);
void leftRight(Node*& node);
void rightLeft(Node*& node);
public:
AVLTree();
~AVLTree();
AVLTree(const AVLTree &c);
AVLTree(AVLTree &&c);
AVLTree &operator=(const AVLTree &c);
AVLTree &operator=(AVLTree &&c);
void add(T value);
int getHeight(Node* n);
};
template <typename T>
AVLTree<T>::AVLTree()
:head{nullptr}{
}
template <typename T>
AVLTree<T>::~AVLTree(){
}
template <typename T>
void AVLTree<T>::rightRotate(Node*& node){
Node* temp = node;
node = node->left;
Node* leftLL = node->right;
temp->left = leftLL;
node->right = temp;
}
template <typename T>
void AVLTree<T>::leftRotate(Node*& node) {
Node* temp = node;
node = node->right;
Node* yL = node->left;
temp->right = yL;
node->left = temp;
}
//left right condition
template <typename T>
void AVLTree<T>::leftRight(Node*& node) {
leftRotate(node->left);
rightRotate(node);
}
//right left condition
template <typename T>
void AVLTree<T>::rightLeft(Node*& node){
rightRotate(node->right);
leftRotate(node);
}
template <typename T>
void AVLTree<T>::add(T value){
if(head==nullptr){
head = new Node(value);
return;
}
std::stack<Node*> st;
Node* it = head;
while(it!=nullptr){
st.push(it);
if(value <= it->val){
it = it->left;
}else{
it=it->right;
}
}
//here is where the it is not assigned to the new node pointer.
//I have tested it and the node is created, "it" just does not hold the value at any point.
it = new Node(value);
int count = 0;
while(!st.empty()){
int balance = getHeight(st.top()->left) - getHeight(st.top()->right);
if(balance > 1){
if(st.top()->left!= nullptr&&st.top()->left!=nullptr){
leftRotate(st.top());
}else{
leftRight(st.top());
}
}else if(balance<-1){
if(st.top()->right!=nullptr&&st.top()->right!=nullptr){
rightRotate(st.top());
}else{
rightLeft(st.top());
}
}
st.pop();
if(++count==4){
break;
}
}
}
template <typename T>
int AVLTree<T>::getHeight(Node* n){
int max =0;
if(n!=nullptr){
max = std::max(getHeight(n->left),getHeight(n->right))+1;
}
return max;
}
#endif /* AVLTree_hpp */
It is a copy of the pointer and updating it has no effect on the original pointer. You need to do something like this instead:
Node* it = head;
bool left = true;
while(it!=nullptr){
st.push(it);
left = value <= it->val;
if(left){
it = it->left;
}else{
it=it->right;
}
}
it = new Node(value);
if (left){
stack.top()->left = it;
} else {
stack.top()->right = it;
}
Consider this simplified version of your code:
#include <iostream>
struct Linked {
Linked* next;
};
int main(int argc, char** argv) {
Linked l0 {nullptr};
// Case 1: Does not work
std::cout << "case 1" << std::endl;
Linked* node = l0.next;
node = new Linked {nullptr};
std::cout << "node=" << std::hex << node << std::endl;
std::cout << "l0.next=" << std::hex << l0.next << std::endl;
free(node);
std::cout << std::endl;
// Case 2: Works
std::cout << "case 2" << std::endl;
l0.next = new Linked {nullptr};
std::cout << "l0.next=" << std::hex << l0.next << std::endl;
free(l0.next);
l0.next = nullptr;
std::cout << std::endl;
// Case 3: Works
std::cout << "case 3" << std::endl;
Linked** nodeP = &(l0.next);
*nodeP = new Linked {nullptr};
std::cout << "*nodeP=" << std::hex << *nodeP << std::endl;
std::cout << "l0.next=" << std::hex << l0.next << std::endl;
free(l0.next);
l0.next = nullptr;
}
Which outputs:
$ ./main
case 1
node=0x7fba0d400620
l0.next=0x0
case 2
l0.next=0x7fba0d400620
case 3
*nodeP=0x7fba0d400620
l0.next=0x7fba0d400620
Case 1: does not work because the new Node is assigned to a copy of the left/right child pointer (i.e. not the actual child node from the parent node)
Case 2: works as expected because the new node is assigned directly to one of the parent's child node.
Case 3: also works because instead of assigning the new node to a copy of the child pointer, you assign it to a pointer referencing the pointer to child itself. In this respect, case 2 and 3 are equivalent.

An implementation of Stack in C++ using doubly LL fails with an exception “EXC_BAD_ACCESS (code=2, address=0x7fff5df48ff8)”

Goal:
I've implemented a stack using a doubly linked list. I'm using a doubly linked list because the input size is 1 billion and using any other data structure will not render an optimal solution.
Problem:
I have two objects declared in the class MyStack() called root and tail. I want to initialize the values of these two objects to NULL initially. Later, when I call the push() method for the first time, it'll override the values of objects root and tail.
In my case, the code fails with an exception, “EXC_BAD_ACCESS (code=2, address=0x7fff5df48ff8) because the value of root is not NULL. I'm not sure where I should be initializing the values so that root and tail don't get overridden until push() is called.
The following is the .h file:
#ifndef UNTITLED_MYSTACK_H
#define UNTITLED_MYSTACK_H
class MyStack {
void* data;
MyStack* next;
MyStack* prev;
MyStack* root;
MyStack* tail;
public:
MyStack();
MyStack(void *data);
MyStack * newNode();
void *newNode(void* data);
bool isEmpty(MyStack *root);
void push(void *data);
void *pop();
int size();
virtual ~MyStack();
};
#endif //UNTITLED_MYSTACK_H
The following is the .cpp file
#include <iostream>
#include <climits>
#include <cstdlib>
#include "MyStack.h"
using namespace std;
MyStack::MyStack() : root(NULL), tail (NULL) {} // <-- ERROR here -->
MyStack::MyStack(void *data) : data(data) {} // <-- ERROR here -->
MyStack * MyStack::newNode()
{
MyStack* stackNode;
stackNode = new MyStack();
stackNode->data = NULL;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
void* MyStack::newNode(void* data)
{
MyStack* stackNode;
stackNode = new MyStack(data);
stackNode->data = data;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
bool MyStack::isEmpty(MyStack *root) {
return (root == NULL);
}
void MyStack::push(void *val) {
if (isEmpty(root)) {
root->data = newNode(val);
tail->data = newNode(val);
tail->next = newNode();
tail = tail->next;
root->next = tail;
tail->prev = root;
cout << " Element pushed to stack" << tail->data << endl;
}
else {
tail->data = val;
tail->next = newNode();
tail->next->prev = tail;
tail = tail->next;
cout << " Element pushed to stack" << tail->data << endl;
}
}
void *MyStack::pop() {
if (isEmpty(tail)) {
cout << "Stack is empty" << endl;
return NULL;
}
MyStack* evictedN = new MyStack();
evictedN = tail;
tail = tail->prev;
tail->next = newNode();
tail = tail->next;
return evictedN->data;
}
int MyStack::size() {
if(isEmpty(root)) {
cout << "Size is empty" << endl;
return 0;
}
int count = 1;
while (tail->prev != NULL) {
count += 1;
tail = tail->prev;
}
return count;
}
MyStack::~MyStack() {
}
//here is my main method
int main() {
MyStack s;
elem_t* elem;
elem->value = 10;
elem->other = 10 >> 1;
s.push(elem);
cout << elem->value << endl;
cout << elem->other << endl;
cout << s.pop() << endl;
cout << s.size() << endl;
return 0;
}
The main problem is that you are not distinguishing between the stack and the nodes that the stack contains. MyStack::newNode() is returning a completely new stack, not a new node. According to this code:
void MyStack::push(void *val) {
if (isEmpty(root)) {
root->data = newNode(val);
tail->data = newNode(val);
tail->next = newNode();
tail = tail->next;
root->next = tail;
tail->prev = root;
cout << " Element pushed to stack" << tail->data << endl;
}
else {
tail->data = val;
tail->next = newNode();
tail->next->prev = tail;
tail = tail->next;
cout << " Element pushed to stack" << tail->data << endl;
}
}
in the case where the root is NULL, isEmpty(root) returns true, so we go ahead and dereference it anyway by accessing root->data. This is undefined behavior.
You need to distinguish between a node and a stack and rewrite the code with that distinction in mind. elem_t could be the node type, or you could define a new class.
here is the MyStack_class.h file:
#ifndef MYSTACK_CLASS_H
#define MYSTACK_CLASS_H
class elem_t {
public:
int value;
int other;
elem_t() {};
elem_t(int value, int other) : value(value), other(other) {}
~elem_t() {};
};
class MyStack {
private:
void* data;
MyStack* next;
MyStack* prev;
public:
MyStack () {}
MyStack(void* val) : data(val), next(nullptr), prev(nullptr) {}
~MyStack() {}
MyStack* newNode();
MyStack* newNode(void*);
void push(void*);
void* pop();
int size();
};
#endif
~
The following is the MyStack_class.cpp file:
#include <iostream>
#include "MyStack_class.h"
#include <cstdlib>
using namespace std;
int count = 0;
MyStack* root = new MyStack();
MyStack* tail = new MyStack();;
MyStack* MyStack::newNode()
{
MyStack* stackNode;
stackNode = new MyStack();
stackNode->data = NULL;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
MyStack* MyStack::newNode(void* data)
{
MyStack* stackNode;
stackNode = new MyStack(data);
stackNode->data = data;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
void MyStack::push (void* val)
{
if (count == 0) {
root = newNode(val);
tail = newNode(val);
tail->next = newNode();
tail = tail->next;
root->next = tail;
tail->prev = root;
count++;
cout << "Element: " << count << " pushed to Stack" << endl;
}
else {
tail->data = val;
tail->next = newNode();
tail->next->prev = tail;
tail = tail->next;
count++;
cout << " Element " << count << " pushed to stack" << endl;
}
}
void* MyStack::pop()
{
if (count == 0) {
cout << "Stack is empty" << endl;
exit(1);
}
MyStack* evictedN = new MyStack();
tail = tail->prev;
evictedN = tail;
tail->next = tail->next->prev = NULL;
count--;
return evictedN->data;
}
int MyStack::size() {
int cnt = 0;
while(root->next != NULL) {
cnt++;
root = root->next;
}
return cnt;
}
The MyStack_class library is used in the following program which can be called
main.cpp or anything that you'd like:
#include <iostream>
#include <cstdlib>
#include "MyStack_class.h"
#define NELEM 1000
using namespace std;
void
example() {
MyStack* s = new MyStack;
for (int i = 0; i < NELEM; i++) {
elem_t* elem = new elem_t(i , i >> 1);
if (elem == NULL) {
exit(1);
}
s->push(elem);
cout << "the pushed element's value and other respectively : " << elem->value << " " << elem->other << endl;
}
cout << "Stack size : " << s->size() << endl;
for (int i = (NELEM-1); i > 0; i--) {
elem_t* elem = static_cast<struct elem_t*>(s->pop());
if (elem->value != i) {
cout << "Error: i is " << i << "and elem-value is " << elem->value << endl;
}
cout << "The popped element's value and other respectively: " << elem->value << " " << elem->other << endl;
delete elem;
}
delete s;
}
int
main()
{
example();
return 0;
}
Here's how my Makefile looks:
MyStack_class: MyStack_class.o main.o
g++ MyStack_class.o main.o -o MyStack_class
MyStack_class.o: MyStack_class.cpp main.cpp
g++ -c -std=c++0x MyStack_class.cpp main.cpp
clean:
rm MyStack_class.o main.o MyStack_class

Linked lists insertion (core dumped)

my header and implimentation file
#ifndef VIKTOR_H_
#define VIKTOR_H_
#include <iostream>
template <class DataType>
class viktor {
private:
template <class NodeType>
struct Node {
NodeType data;
Node<NodeType> * next;
};
Node<DataType> * backPtr;
int length;
public:
viktor();
~viktor();
DataType &operator [] (int) const;
void push(const DataType &);
friend std::ostream &operator << (std::ostream &strm, const
viktor<DataType> &A){
for(int i = 0; i < A.length; ++i) {
strm << A[i] << " " << std::flush;
}
strm << std::endl;
return strm;
}
};
template <class DataType>
viktor<DataType>::viktor() {
backPtr = nullptr;
length = 0;
}
template <class DataType>
viktor<DataType>::~viktor() {
if ( length == 0 ) return;
Node<DataType>* previousPtr = backPtr;
Node<DataType>* nextPtr = backPtr->next;
while( nextPtr != backPtr )
{
nextPtr = nextPtr->next;
previousPtr->next = nullptr;
delete previousPtr;
length--;
}
backPtr->next = nullptr;
delete backPtr;
}
template <class DataType>
void viktor<DataType>::push(const DataType &item) {
Node<DataType>* newNode = new Node<DataType>;
newNode->data = item;
std::cout << "data: " << newNode->data << std::endl;
if(length != 0) {
newNode->next = backPtr->next;
backPtr->next = newNode;
}
else {
newNode->next = newNode;
}
backPtr = newNode;
length += 1;
//std::cout << "Finished pushing..." << std::endl;
}
template <class DataType>
DataType &viktor<DataType>::operator [] (int i) const {
Node<DataType>* conductor = backPtr;
if (i > length) {
throw "Item is inaccessible";
}
for (int j = 0; j <= i; ++j) {
conductor = conductor->next;
}
return conductor->data;
}
#endif //VIKTOR_H_
i am having problems with this function
template <class DataType>
void viktor<DataType>::push(const DataType &item) {
Node<DataType>* newNode = new Node<DataType>;
newNode->data = item;
std::cout << "data: " << newNode->data << std::endl;
if(length != 0) {
newNode->next = backPtr->next;
backPtr->next = newNode;
}
else {
newNode->next = newNode;
}
backPtr = newNode;
length += 1;
//std::cout << "Finished pushing..." << std::endl;
}
i am using this test driver
int main() {
viktor<int> blah;
blah.push(2);
std::cout << blah << std::endl;
}
now it works if i only push once but if i do
blah.push(1);
blah.push(2);
it runs and prints all of the data that i want but at the end of the program it dumps my core (i can provide the specific error if you want but it's just a memory map and then aborted (core dumped))
i fixed it! thanks Some programmer dude! so the problem was my deconstructor, what i did was changed previousPtr->next = nullptr; to previousPtr = previousPtr->next;

Inserting two elements in node template in a doubly linked list

I'm new with data structures in C++, and i'm trying to do a doubly linked list with templates. All the examples that i have seen are only for 1 element of the template node, so i'm trying to put 2 elements in the template node in the list, but i don't know how to do it, anyway, i tried to make the list.
Here's the code:
#include<iostream>
#include<cstring>
using namespace std;
template<class T>
// node class
class node
{
public:
node();
node(T);
~node();
node *next;
T data[2];
void borra_todo();
void print();
};
// by defect
template<typename T>
node<T>::node()
{
data[0] = NULL;
data[1] = NULL;
next = NULL;
}
// by parameter
template<typename T>
node<T>::node(T data_)
{
data[0] = data_[0];
data[1] = data_[1];
next = NULL;
}
// delete nodes
template<typename T>
void node<T>::borra_todo()
{
if (next)
next->borra_todo();
delete this;
}
// node printing
template<typename T>
void node<T>::print()
{
cout << data[0] << " " << data[1] << "->";
}
template<typename T>
node<T>::~node() {}
// list
template <class T>
class list
{
private:
node<T> *m_head;
int m_num_nodes;
public:
list();
~list();
void add_head(T);
void add_end(T);
void add_sort(T);
void fill(char r[30], char n[30]);
void search(T);
void del_by_data(T);
void print();
};
template<typename T>
list<T>::list()
{
m_num_nodes = 0;
m_head = NULL;
}
//add in the beginning
template<typename T>
void list<T>::add_head(T data_)
{
node<T> *new_node = new node<T>(data_);
node<T> *temp = m_head;
if (!m_head)
{
m_head = new_node;
}
else
{
new_node->next = m_head;
m_head = new_node;
while (temp)
{
temp = temp->next;
}
}
m_num_nodes++;
}
// add to the last
template<typename T>
void list<T>::add_end(T data_)
{
node<T> *new_node = new node<T> (data_);
node<T> *temp = m_head;
if (!m_head)
{
m_head = new_node;
}
else
{
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new_node;
}
m_num_nodes++;
}
// it is supposed that sorts items in the list ...
template<typename T>
void list<T>::add_sort(T data_)
{
node<T> *new_node = new node<T> (data_);
node<T> *temp = m_head;
if (!m_head)
{
m_head = new_node;
}
else
{
for (int i =0; i <= 1; i++)
{
if (m_head->data[0] > data_[i])
{
new_node->next = m_head;
m_head = new_node;
}
else
{
while ((temp->next != NULL) && (temp->next->data[0] < data_[i]))
{
temp = temp->next;
}
new_node->next = temp->next;
temp->next = new_node;
}
}
m_num_nodes++;
}
}
// sort adding ...
template<typename T>
void list<T>::fill(char rfc[30])
{
char temprfc[30];
char tempnombre[30];
temprfc = "DUDE010101R0";
tempnombre = "Dude";
add_sort(temprfc, tempnombre);
temprfc = "AUDE010101R1";
tempnombre = "Commander";
add_sort(temprfc, tempnombre);
}
// print list
template<typename T>
void list<T>::print()
{
node<T> *temp = m_head;
if (!m_head)
{
cout << "List is empty" << endl;
}
else
{
while (temp)
{
temp->print();
if (!temp->next)
cout << "NULL\n";
temp = temp->next;
}
}
cout << endl;
}
// search the list
template<typename T>
void list<T>::search(T data_)
{
node<T> *temp=m_head;
int cont=1;
int cont2=0;
while(temp)
{
if(strcmp(temp->data,data_[0]))
{
cout<<"Element found " << temp->data;
cout << " in position: " << cont << endl;
cont2++;
}
temp=temp->next;
cont++;
}
if(cont2==0)
{
cout << "Element not found"<<endl;
}
}
// ... delete by data
template<typename T>
void list<T>::del_by_data(T data_)
{
node<T> *temp = m_head;
node<T> *temp1 = m_head->next;
int cont =0;
if (m_head->data == data_)
{
m_head = temp->next;
}
else
{
while (temp1)
{
if (temp1->data == data_)
{
node<T> *aux_node = temp1;
temp->next = temp1->next;
delete aux_node;
cont++;
m_num_nodes--;
}
temp = temp->next;
temp1 = temp1->next;
}
}
if (cont == 0)
{
cout << "No data" << endl;
}
}
// destroy the constructor
template<typename T>
list<T>::~list() {}
int main()
{
list<char> list1;
char element1[30];
char element2[30];
int dim, choice, pos;
do{
cout << "Select a choice.\n";
cout << "1. Print list\n";
cout << "2. Delete an element of the list\n";
cout << "3. Search an element of the list\n";
cout << "4. Exit\n";
cin >> choice;
switch(choice)
{
case 1:
{
cout << "Printing list:\n";
list1.fill("1","2");
list1.print();
break;
}
case 2:
{
cout << "Element to delete: ";
cin >> element1;
list1.search(element1);
element1 = "";
break;
}
case 3:
{
cout << "Element to search: ";
cin >> element1;
list1.search(element1);
element1 = "";
break;
}
}
}while(choice != 4);
return 0;
}
The code doesn't compile, it marks errors like:
" error: prototype for ‘void list::fill(char*)’ does not match any in class ‘list’
void list::fill(char rfc[30])
^
t3b.cpp:79:8: error: candidate is: void list::fill(char*, char*)
void fill(char r[30], char n[30]);"
Any ideas on how to fix it? Or any ideas on how to put 2 elements in a node using templates?
Thanks in advance.
Dude, you should really try to isolate the error a little bit before posting it. This is 500 lines of code, I had to copy and paste it all into an editor before I could even look at it.
When you declared fill, it had two arguments, when you defined it, it had one. Also, I would avoid arrays of characters for numerous reasons, instead use std::string.