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.
Related
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 :)
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 3 years ago.
Improve this question
I am new to coding, so please forgive me if this question seems stupid. I was writing my own List class to get a better understanding of how Lists are structured, but I ran into an issue. I dynamically allocated my list as I added more items to it, and the deconstructor on my program ran just fine with ints. However, as I was testing with std::string, I ran into an issue. It keeps throwing exceptions after my deconstructor is called(, even though (I'm fairly certain) I deleted the memory I allotted alone, and not theirs (read access violation).
I've tried using smart pointers instead of deleting the allocated memory in my deconstuctor, but that ends up having the same issue. Looking online, all I can seem to find is, "only delete with deconstructors," and, "don't have exception handling in deconstructors." Both of which are not even issues with what I've written.
Here is firstly, the relevant code (in my mind) to solving this.
#include <string>
#include <iostream>
using std::cout;
using std::cin;
using std::string;
template <class type>
class List
{
struct Node
{
type data;
Node* next;
};
public:
List();
~List();
void addToList(type var);
private:
Node head;
Node *last, *lastAcc;
unsigned int length, prevPos;
};
template <class type>
List<type>::~List()
{
Node *prevPtr;
lastAcc = head.next;
while (lastAcc->next) // While the next pointer leads to something
{
// Go to that something, and delete the item you were on
prevPtr = lastAcc;
lastAcc = lastAcc->next;
delete prevPtr;
}
delete lastAcc;
}
template <class type>
void List<type>::addToList(type var)
{
if (length)
{
last->next = new Node;
last = last->next;
last->data = var;
}
else
{
head.data = var;
}
lastAcc = last;
prevPos = length++;
}
template <class type>
List<type>::List()
{
head.next = 0;
prevPos = 0;
lastAcc = last = &head;
length = 0;
}
int main()
{
string boi[] = { "Today is a good day", "I had an apple", "It tasted delicious" };
List<string> multiString;
for (int i = 0; i < 3; i++)
{
multiString.addToList(boi[i]);
}
return 0;
}
I expected the code to run just fine, and if I made an error, I thought the error would show up on my code. Not on std::string. Any help would be greatly appreciated.
[Edit] On an added note, [lastAcc] is abbreviated for last accessed; it's just something I implemented to make going through the lists faster than just having to start from 0 every time. [prevPos] shows the position of [lastAcc] in the list. Let me know if you need to see more of my code or explain anything~!
you aren't initialising last->next in addToList so iteration in your destructor falls off the end of the list. The correct code is:
void List<type>::addToList(type var)
{
if (length)
{
last->next = new Node();
last = last->next;
last->data = var;
}
else
{
head.data = var;
}
lastAcc = last;
prevPos = length++;
}
The difference is new Node() rather than new Node. The first value initialises POD types, the second doesn't.
Alternatively if you define a constructor for Node then new Node and new Node() will be equivalent:
struct Node
{
Node(): next( 0 ) {}
type data;
Node* next;
};
For a small efficiency gain you could move your value into your node to prevent copies:
struct Node
{
Node(): next( 0 ) {}
Node(type && data): data( std::move( data ) ), next( 0 ) {}
type data;
Node* next;
};
template <typename T>
void addToList(T&& var)
{
if (length)
{
last->next = new Node(std::move(var));
last = last->next;
}
else
{
head.data = std::move(var);
}
lastAcc = last;
prevPos = length++;
}
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 5 years ago.
Improve this question
There are many errors in my codes.
But i don't know about wrong things...
There are common error massages such that "invalid use of template-name
‘node’ without an argument list", "‘head_ptr’ was not declared in this
scope", "‘tail_ptr’ was not declared in this scope",
"‘t’ was not declared in this scope" ,
"template argument 1 is invalid", "expected type-specifier before ‘Node’"
I don't think my overall code is wrong.
But too many error make me to think
all of composition of coding is error..
It is a part of all code.
error explanation
template <typename T>
Node* Node<t>::getNext(void)
{ return next; }
template <typename T>
class List
{
private:
Node* head_ptr; Node* tail_ptr; int numOfItems;
public:
List(); //constructor
int size(void); bool isEmpty(void);
void insertTail(T x);
void removeHead(void);
Node<T>* getHead(void);
Node<T>* getTail(void);
void insert_with_priority(T x);
};
template <typename T>
List<T>::List()
{ head_ptr = NULL; tail_ptr = NULL; numOfItems = 0; }
template <typename T>
void List<T>::insertTail(T x){
Node<t>* newTail = new Node(x);
tail_ptr->setNext(newTail);
tail_ptr = newTail;
numOfItems++;
}
template <typename T>
void List<T>::removeHead(void){
if(numOfItems == 0)
return 0;
if(numOfItems == 1){ //i.e. headptr == tail_ptr
delete head_ptr; head_ptr = NULL; tail_ptr = NULL;
'
Please give me many feedback.
Even though your question is incomplete, I'll help you with one of the errors (and it might solve other follow-up errors as well)...
Lets take the lines
template <typename T>
Node* Node<t>::getNext(void)
{ return next; }
You say that the getNext function returns a pointer to Node. But, in this instance what is Node? It's not a class or a type, it's a template for a class or type. It's not complete. You need to specify the full and complete class or type:
template <typename T>
Node<T>* Node<t>::getNext(void)
{ return next; }
Note the return-type which is now a full class.
I've stumbled upon a problem with my linked list class.
I've one abstract class Shape and multiple classes inheriting from it, like Square or Triangle etc.
I'm storing them in my List class but I don't know how to return stored object back to the pointer of Shape.
Since my explanation may seem pretty vague here is some code with expected behaviour explained.
class Shape // abstract class
{
public:
int a;
//some member virtual methods
};
class Square : public Shape
{
//using the virtual methods from Shape
};
In my main file, this is how I want to use it:
int main()
{
List<Shape*> ShapeList;
Shape *ptr;
Square a(2, 1, 1); // size, x, y coordinates
ShapeList.add(ptr);
//up to this point everything works well
// now I want my list to return a pointer to it's member
// so I can modify it
Shape *listptr;
listptr = ShapeList.findInstanceAt(0); // here's my error
listptr->a = 5; // what I want to do next
}
So as you can see I'm havingtroubles with returning proper value from my list and I don't know how to solve this.
Here's my simplified list implementation:
template <class T> class Node
{
T data;
Node *next;
public:
inline T getData()
{
return data;
}
inline Node* getNext()
{
return next;
}
};
template <class T> class List
{
Node<T> *head, *tail;
public:
List() : head(NULL), tail(NULL) { }
T* findInstanceAt(int _k)
{
if (NULL == head)
{
cout << "\nList is empty.";
return NULL;
}
else
{
Node<T> *temp = new Node<T>;
temp = head;
for (size_t k = 0; k < _k; ++k)
{
if (NULL != temp->getNext()) temp = temp->getNext();
else return NULL;
}
return temp->getData;
}
}
}
Thanks in advance for any suggestions on how to make this work.
#EDIT
Ahh I forgot to add compiler errors that I'm getting:
Error 1 error C2440: '=' : cannot convert from 'Shape **' to 'Shape *'
Do you want to store Shapes or pointers to Shapes in the list? And do you want the findInstanceAt to return the node in the list or a pointer to the node in the list? At the moment you are not consistent on these things
You store Shape* nodes in the list but the findInstanceAt returns a pointer to the node - which is a Shape** object. This is what the compiler is complaining about
You probaly need to chang
T* findInstanceAt(int _k)
to
T findInstanceAt(int _k)
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...