C++: Simple Node/Linked List [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
In the following Linked List I am trying to implement a print function. The function is templated, and is not a part of the Node class.
Basically I want this print function to be dynamic, so that I don't have to print out all of the Node->data manually. I am kind of working along the lines of this example: http://www.cstutoringcenter.com/tutorials/cpp/cpp17.php
However, when I try to implement the print function I get compiler errors such as:
node was not declared in this scope, p' was not declared in this scope, and variable or field 'print' declared void.
Here is my program:
#include<iostream>
using namespace std;
template<typename T>
class Node
{
public:
Node(T = 0);
~Node() { delete [] nextPtr; };
T getData() const;
Node<T>*& getNextPtr() { return nextPtr; };
private:
T data;
Node<T> *nextPtr;
};
//CONSTRUCTOR
template<typename T>
Node<T>::Node(T newVal)
: data(newVal), nextPtr(NULL)
{
//EMPTY
};
//GETDATA() -- RETURN DATA VALUE
template<typename T>
T Node<T>::getData() const
{
return data;
};
//PRINT FUNCTION
template<typename T>
void print(node<T>* p)
{
while(p)
{
cout << p->data();
p = p->link();
}
};
int main()
{
Node<int> intNode1(5), intNode2(6), intNode3(7);
intNode1.getNextPtr() = &intNode2;
intNode2.getNextPtr() = &intNode3;
print(&intNode1);
system("pause");
}
What am I doing wrong?

There are a few issues, you mistyped Node and you are not using the interface correctly, this will compile:
template<typename T>
void print(Node<T>* p)
{
while(p)
{
cout << p->getData() << std::endl;
p = p->getNextPtr();
}
}
Added std::endl to make sure you see output. Also the way you are using the class your destructor will be calling delete on non dynamically allocated data. Since intNode2 and intNode3 are allocated on the stack. You are also using array delete delete [] you should be using delete. This is potential fix for main:
int main()
{
Node<int> intNode1(5) ;
Node<int> *nPtr = intNode1.getNextPtr() = new Node<int>(6);
nPtr->getNextPtr() = new Node<int>(7) ;
print(&intNode1);
system("pause") ; // This is not portable
}

you print function:
template<typename T>
void print(node<T>* p)
should be:
template<typename T>
void print(Node<T>* p)
//^^^^
Since there no node class template defined in your code.
EDIT: there are no link() and data() defined in Node class.

Maybe you meant to type Node rather than node, seeing as you use Node<T> everywhere else...

Related

deleting a object by calling a method it belongs

I have been learning and playing around C++ (mostly, pointers and dynamic memory allocation) for few days and I tried to create a generic class for linked list.
The classes
#include <cstdint>
#define _LINKEDLIST_DEFAULT_MAX_SIZE 2147483647L
template <typename T>
class LinkedList;
template <typename T>
class LinkedListNode;
template <typename T>
class LinkedListNode final
{
private:
LinkedListNode<T> *nextNode{nullptr};
friend LinkedList<T>;
public:
T data{};
};
template <typename T>
class LinkedList final
{
private:
LinkedListNode<T> *firstNode{nullptr};
std::int32_t maxLength{};
std::int32_t currentLength{};
public:
LinkedList(std::int32_t max_size = _LINKEDLIST_DEFAULT_MAX_SIZE)
{
maxLength = max_size;
}
void addFirst(LinkedListNode<T> *nodePtr)
{
if (firstNode == nullptr)
{
firstNode = nodePtr;
return;
}
nodePtr->nextNode = firstNode;
firstNode = nodePtr;
}
void clerList()
{
// code of releasing occupied heap memory back
}
}
Main method
int main()
{
LinkedList<short> *head{new LinkedList<short>()};
LinkedListNode<short> *node1{new LinkedListNode<short>()};
LinkedListNode<short> *node2{new LinkedListNode<short>()};
node1->data = 1;
node2->data = 2;
head->addFirst(node1);
head->addFirst(node2);
return 0;
}
And this works as properly so far as variables in my debugger shows expected results.
But my issue is how could I write my clearList() method on LinkedList<T> class? I can traverse through LinkedListNode<T> objects and release their memory back calling delete(), but calling delete(this) from clearList() to release back the memory of LinkedList<T> object at first sounds like suiciding since it tries to delete the object which it belongs to. (Note that some simple validation logics have not yet been put into the code)
Do you have any ideas to make this happen :)

Getting segmentation fault core dumped error [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
When I try to create the object of graph and pointer object of Edge it gives me segmentation fault while when I only create the graph object it does not gives me the error but when I create the graph object and Edge pointer object simultaneously it gives me the segmentation error. Why is it so? When I delete the line where the edge pointer object is declared in the main function then the code works fine but I need an edge object to display the edges...
The same code I run in any online c++ compiler gives me the correct output without any error.
#include <iostream>
using namespace std;
template <class B>
struct Edge
{
B vertex;
Edge<B> *next;
};
template <class A>
struct VertexNode
{
Edge<A> *edgeHead;
A vertex;
VertexNode *nextVertex;
};
template <class A>
class Graph
{
private:
VertexNode<A> *head;
public:
Graph();
void insertVertex(A vertex);
bool insertEdge(A vertex1, A vertex2); // this would return true if the both the vertices exists otherwise false
bool deleteVertex(A vertex); // this would return true if the vertex exists otherwise false
bool deleteEdge(A vertex1, A vertex2); // this would return true if the both the vertices exists and the edge between them exists otherwise false
bool isEmpty();
Edge<A> *Adjacent(A vertex);
};
template <class A>
Graph<A>::Graph()
{
head->edgeHead = NULL;
head->nextVertex = NULL;
head = NULL;
}
template <class A>
Edge<A> *Graph<A>::Adjacent(A vertex) // would return the list head of the edges
{
for (VertexNode<A> *temp = head; temp != NULL; temp = temp->nextVertex)
{
if (temp->vertex == vertex)
{
return temp->edgeHead;
}
}
return NULL;
}
template <class A>
bool Graph<A>::isEmpty()
{
return (head == NULL);
}
int main()
{
Graph<char> obj;
Edge<char> *edgeHead; // for displaying the list of edges
// adding vertices
obj.insertVertex('A');
obj.insertVertex('B');
obj.insertVertex('C');
obj.insertVertex('D');
obj.insertVertex('E');
obj.insertEdge('A', 'C');
// now displaying adjacent edges for checking that our graph is implemented correctly
edgeHead = obj.Adjacent('A');
}
Removing unnecessary code, we get:
template <class A>
class Graph {
VertexNode<A> *head;
Graph();
};
template <class A> Graph<A>::Graph() {
head->edgeHead = NULL;
head->nextVertex = NULL;
head = NULL;
}
At no point is memory allocated for head, so you are dereferencing an uninitialized value. That will often lead to a segmentation fault.

Using or not using new for creation of a class in another

I have been solving a question, Dijkstra's Algorithm, in C++. I've implemented it using adjacency list.
So I have a class for a node, a class for a minHeap, and a class for the Graph.
class node
{
int vertex,weight;
node *next;
friend class Graph;
friend class minHeap;
public:
node();
node(int,int);
};
node::node(){
vertex=weight=0;
next=0;
}
node::node(int v,int wt){
vertex=v;
weight=wt;
next=0;
}
Do I define the minHeap class this way (without a friend function) and create an object in the getDijkSP() function normally, which allows me to use the object only in that function?
class minHeap
{
node *heap;
int heapSize,capacity,*pos;
public:
minHeap(int);
void addElement(node);
node extractMin();
void minHeapify(int);
void decreaseKey(int,int);
};
minHeap::minHeap(int cap){
heap=new node[capacity=cap];
heapSize=-1;
pos=new int[cap]();
} //eliminating other methods
class Graph
{
node **adjList;
int v;
bool *visited;
public:
Graph(int);
void addEdge(int,int,int);
void removeEdge(int,int);
bool existsEdge(int,int);
void getDijkSP();
};
Graph::Graph(int vertices){
adjList=new node*[v=vertices];
for(int i=0;i<v;i++)
adjList[i]=NULL;
}
void Graph::getDijkSP(){
minHeap hp(v); //here
hp.addElement(node(0,0));
for(int i=1;i<v;i++)
hp.addElement(node(i,INT_MAX));
while(!hp.isempty()){
node temp=hp.extractMin();
cout<<temp.vertex<<" "<<temp.weight<<endl;
for(node *current=adjList[temp.vertex];current;current=current->next)
hp.decreaseKey(current->vertex,current->weight+temp.weight);
}
}
(OR) Do I define the minHeap class with a friend function, so that I can create an object of the minHeap class using the new keyword? (And this helps me define the minHeap object in the scope of the Graph class, so that I can use it in all of its functions for other capabilities as well.)
class minHeap
{
node *heap;
int heapSize,capacity,*pos;
friend class Graph; //say like this
public:
minHeap(int);
void addElement(node);
node extractMin();
void minHeapify(int);
void decreaseKey(int,int);
};
minHeap::minHeap(int cap){
heap=new node[capacity=cap]();
heapSize=-1;
pos=new int[cap]();
}
class Graph
{
node **adjList;
int v;
bool *visited;
minHeap *hp; //and do this
public:
Graph(int);
void addEdge(int,int,int);
void removeEdge(int,int);
bool existsEdge(int,int);
void getDijkSP();
};
Graph::Graph(int vertices){
adjList=new node*[v=vertices];
for(int i=0;i<v;i++)
adjList[i]=NULL;
hp=new minHeap(v); //dynamic allocation
}
void Graph::getDijkSP(){
hp->addElement(node(0,0));
for(int i=1;i<v;i++)
hp->addElement(node(i,INT_MAX));
while(!hp->isempty()){
node temp=hp->extractMin();
cout<<temp.vertex<<" "<<temp.weight<<endl;
for(node *current=adjList[temp.vertex];current;current=current->next)
hp->decreaseKey(current->vertex,current->weight+temp.weight);
}
}
I have read this and a few other articles, but specifically want to know the advantages, disadvantages and the appropriateness of both the methods for such similar kinds of questions.
I've provided the constructors for the classes for better clarity.
Short answer would be NO. I would suggest you to read up on smart pointers and rewrite this whole mess. In C++ there is no real reason to use manual allocation in so simple project as this ever.
Also instead of assigning 0 or NULL to a pointer use nullptr, which is C++ symbol only for null pointers unlike the previous mentioned C values that are actually just a int 0 which may cause some unintentional errors.
Edit in response to your comment:
So I've decided to rewrite your code using actual modern C++ instead of this C code with simple classes. In your whole example there are almost no pointers or dynamic allocations needed. I wasn't absolutely sure who exactly should own the actual nodes so from the example I assumed that the MinHeap should. Also I didn't get the point of MinHeap::pos and Graph::visited from what I could see. I can explain any part of that code in more detail, just ask which.
Here is the code:
class Node {
// Only friend class required if you insist on keeping members of Node private.
// If they aren't meant to change, consider declaring them as public and const.
template <unsigned Size> friend class Graph;
public:
Node(int v, int wt) : vertex(v), weight(wt) {}
private:
// Default values written in here right after declarations
// There is no need for a default constructor. You never call it anyway.
int vertex;
int weight;
Node* next = nullptr;
};
// Template parameter because of internal use of std::array.
// If the capacity shouldn't be constant, use std::vector and remove template.
template <unsigned Capacity>
class MinHeap {
public:
// No constructor needed
// ---------------------
// One small tip: write parameter names in function declarations
// even if they aren't needed there for better readability of your code.
void addElement(Node n) { /* impl */ }
Node extractMin() { /* impl */ }
unsigned capacity() { return Capacity; }
bool isEmpty() { return heap.isEmpty(); }
private:
// Default values written in here right after declarations
int heapSize = -1;
std::array<Node, Capacity> heap;
};
// Template parameter because of internal use of std::array.
// If the vertex count shouldn't be constant, use std::vector and remove template.
template <unsigned Vertices>
class Graph {
public:
// No constructor needed
// ---------------------
void getDjikSP() {
hp.addElement({0, 0});
for (unsigned i = 1; i < hp.capacity(); ++i)
hp.addElement({0, INT_MAX});
while (!hp.isEmpty()) {
Node tmp = hp.extractMin();
std::cout << tmp.vertex << " " << tmp.weight << std::endl;
for (Node* current = adjList[tmp.vertex]; current != nullptr; current = current->next)
hp.decreaseKey(current->vertex, current->weight + tmp.weight);
}
}
private:
// Default values written in here right after declarations
std::array<Node*, Vertices> adjList;
MinHeap<Vertices> hp;
};
There is still a lot of space for improvements of this code, for example the MinHeaP::extractMin should maybe return Node&& if it is removed from the heap or const Node& if it should return a reference to the top, etc. To address all the problems and inefficiencies this can still have I would need to see the full code with all functions.

implement queue with linked list [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I wrote the code for implementing queue with linked list, but has some bug that I cannot figure out. When I first push an item into the queue, it works find, but when I tried to push the second one, it gives me runtime error. Could you please help me with it? Thank you very much!
The following is the code:
#include<iostream>
using namespace std;
template<typename T>
struct Node{
T data;
Node* next;
Node(T d, Node* n=NULL): data(d), next(n){}
};
template<typename T>
class myqueue{
private:
Node<T> * first;
Node<T> * last;
public:
myqueue(){}
void push(T da){
if(first==NULL) {
first=new Node<T>(da);
last=first;
}
else {
last->next=new Node<T>(da);
last=last->next;
}
}
void pop(){
if(last!=NULL){
Node<T> * temp=first;
first=first->next;
delete temp;
}
}
void front(){
if(first!=NULL) cout<< first->data;
}
bool isempty(){
return last==NULL;
}
};
int main(){
myqueue<int> q;
q.push(1);
q.push(2);
q.front();
/*
q.push(3);
q.push(4);
q.push(5);
cout<<q.front();
*/
}
compile error: runtime error
Your first and last pointers are uninitialized, so you have undefined behaviour. Initialize them with a member initialization list:
myqueue::myqueue() : first(NULL), last(NULL) {}

How to use a single Template statement for more than one function or struct?

I've been trying to represent Stacks as a template, I used a struct and every thing is good, but every time I wanted to write a template function, I had to write the same template statement, which didn't seem correct -although working-
So how can I write one template statement for all the functions?, here is my code :
template &#60typename T>
struct Stack
{
T Value;
Stack* next;
};
template &#60typename T>
void Push(T Value,Stack* &Top)
{
Stack * Cell = new Stack();
Cell->Value = Value;
Cell->next = Top;
Top = Cell;
};
template &#60typename T>
bool IsEmpty(Stack * Top)
{
return (Top==0);
}
template &#60typename T>
void Pop(T &Value,Stack* &Top)
{
if (IsEmpty(Top))
cout * Temp = Top;
Value = Top->Value;
Top = Top->next;
delete Temp;
}
}
template &#60typename T>
void GetTop(T &Value, Stack* &Top)
{
if (IsEmpty(Top))
cout Value;
}
template &#60typename T>
void EmptyStack(Stack * &Top)
{
Stack * Temp;
while (!(IsEmpty(Top)))
{
Temp = Top;
Top = Top->next;
delete Temp;
}
}
Hope what I mean is clear now, sorry for the slight question :(
thanks in advance.
If (as appears to be the case based on your comment) you want them as free functions, you can't. You'll also have to change the Stack parameter, something like this:
template <typename T>
void Push(T Value, Stack<T>* &Top)
{
Stack * Cell = new Stack();
Cell->Value = Value;
Cell->next = Top;
Top = Cell;
};
As it stands, I'm not too excited about your design though. You try to use the Stack type as both an actual stack, and as a single node (Cell) in the stack. This is unnecessarily confusing at best.
Edit: As far as stack vs. node goes, what I'm talking about is (as in the code immediately above): Stack *Cell = new Stack(); -- you're allocating a single Cell that goes in the stack, but the type you're using for it is Stack.
I'd do something like this instead:
template <class T>
struct Stack {
struct node {
T data;
node *next;
};
node *head;
};
template <class T>
void push(T item, Stack<T> *&s) {
Stack<T>::node *n = new Stack<T>:node();
n->data = item;
n->next = s->head;
s->head = n;
}
It doesn't make a lot of difference in what you're really doing, but when you're putting something onto a stack, allocating a Stack<T>::node seems (at least to me) to make a lot more sense than allocating a Stack<T>. A stack containing multiple nodes makes sense -- a Stack containing multiple stacks really doesn't.
You could simply write a template class instead, and write all those functions as methods of that class. They will then share the same template parameters as the class.