Removing cout causes segmentation fault - c++

this is my code:
template <typename T>
struct Node
{
T info;
Node<T>* next;
};
template<typename T>
struct List
{
Node<T>* n;
int curr;
};
List<T> listCreate()
{
List<T> lst;
lst.curr = 0;
cout << lst.n->info;
lst.n->info = 0;
lst.n->next = NULL;
return lst;
}
If I remove the cout << lst.n->info; it causes a segmentation error. What I want to achieve is to simply create a List and have the next values:
lst:
curr = 0
n:
info = 0
next = NULL
But I can't find a way to achieve this, I tried searching on google and also reading about pointers and structures but I cannot find the problem. It might be a simple problem but I can't find it.
Thanks in advance.

You forgot to initialize lst.n. Accessing uninitialized memory or a nullptr is undefined behavior.
You may do something like this:
List<T> listCreate()
{
List<T> lst;
lst.curr = 0;
// new code
lst.n = new Node<T>();
lst.n->next = nullptr;
// end
cout << lst.n->info;
lst.n->info = 0;
lst.n->next = nullptr;
return lst;
}
Please consider avoiding NULL. You should use nullptr in c++.

Remember dereferencing a null or uninitialized pointer is undefined behavior. You are trying to dereference an uninitialized pointer lst.n->info in your code.

Related

When Class deconstructor is called, std::string throws an 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 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++;
}

Memory Leak in Custom Linked List C++

For an assignment I cannot use a STL list, it must be a custom list. As the title states, I have memory leaks even though I am calling delete on the nodes \ items. I would appreciate any help on this.
List Source
template <typename T>
class DLinkList
{
private:
struct Node
{
T data;
Node *nextNode;
Node *prevNode;
Node(T data, Node *nextNode = nullptr, Node *prevNode = nullptr)
{
this->data = data;
this->nextNode = nextNode;
this->prevNode = prevNode;
}
~Node() { delete data; }
};
Node *head;
Node *tail;
public:
DLinkList();
~DLinkList();
void push_back(T data);
};
template <typename T>
inline void DLinkList<T>::push_back(T data)
{
if (isEmpty())
{
head = new Node(data);
tail = head;
}
else
{
tail->nextNode = new Node(data, nullptr, tail);
tail = tail->nextNode;
}
}
template <typename T>
DLinkList<T>::DLinkList()
{
head = nullptr;
tail = nullptr;
}
template <typename T>
DLinkList<T>::~DLinkList()
{
Node *ptr = head;
while (ptr->nextNode != nullptr)
{
Node *garbage = ptr;
ptr = ptr->nextNode;
delete garbage;
}
}
Foo Class and main
class Foo
{
public:
Foo() { i = 0; d = 0.0; }
Foo(int i, double d) { this->i = i; this->d = d; }
int getInteger() { return i; }
double getDouble() { return d; }
private:
int i;
double d;
};
int main()
{
DLinkList<Foo*> f1;
f1.push_back(new Foo());
f1.push_back(new Foo(2, 5.5));
cout << "1st Values: " << f1.at(0)->getInteger() << ", " << f1.at(0)->getDouble() << endl;
cout << "2nd Values: " << f1.at(1)->getInteger() << ", " << f1.at(1)->getDouble() << endl;
return 0;
}
From valgrind
==12125== 40 (24 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==12125== at 0x4C29203: operator new(unsigned long) (vg_replace_malloc.c:334)
==12125== by 0x400FD8: DLinkList<Foo*>::push_back(Foo*) (DLinkList.hpp:138)
==12125== by 0x400CF3: main (Source.cpp:28)
I am not sure how the memory is being lost here, I want to say that it is because it is making a copy of it and the original is being lost. If this is the case, I am unfamiliar with how to handle it.
Again, I appreciate any help in understanding this. I have tried to look through all related questions, but I did not see anything that covered this or at least I did not understand it. Thank you!
Given the other issues pointed out in the comments such as making an erroneous usage of explicitly calling the DLinkList destructor, you are doing this in main():
f1.push_back(new Foo());
f1.push_back(new Foo(2, 5.5));
You are creating an instant memory leak here on those two lines of code that can not be recovered. You are calling new but nowhere do you save the address returned from new so that you can call delete later on for that address.
So it is main that has to manage these dynamically allocated Foo objects. Something like this:
Foo* p1 = new Foo();
Foo *p2 = new Foo(2, 5.5);
f1.push_back(p1);
f1.push_back(p2);
//...
delete p1;
delete p2;
This should address the memory leak, but this is poor programming practice in this day and age of C++. You would more than likely either use
DLinkList<Foo>
and place Foo objects in the linked list, thus not requiring any manual memory management in main, or use a smart pointer and have a linked list of smart pointers, i.e.
DLinkList<std::unique_ptr<Foo>>
Alright, so I am just exhausted and was missing the simplest thing. After comparing to other lists I created, I realized that my destructor was not deleting the nodes correctly.
template <typename T>
DLinkList<T>::~DLinkList()
{
Node *ptr = head;
while (ptr != nullptr) // Not: ptr->nextNode
{
Node *garbage = ptr;
ptr = ptr->nextNode;
delete garbage;
}
}
But I do want to thank PaulMcKenzie, was a great help and also pointed out that main does need to handle the deletion of the new calls. I will up vote his and mark it.

Simple PUSH function for a C++ stack [duplicate]

This question already has answers here:
Function does not change passed pointer C++
(4 answers)
Closed 5 years ago.
I am trying to implement a simple stack in C++ using a linked list, but I am completely stumped by the PUSH() function. I've been working on it all night and it's nearly driven me bonkers. It should insert an element at the top of the stack, but every way I've tried to implement is has had issues. An excerpt of my relevant code is as follows:
template <typename T>
struct NODE{
T data;
NODE<T> *next;
}
template <typename T>
void PUSH(T x, NODE<T> *S){
NODE<T> *tmp = new NODE<T>;
tmp->data = x;
tmp->next = S;
S = tmp;
}
int main(){
NODE<int> *test = new NODE<int>;
test->data = 111;
test->next = NULL;
PUSH(99, test);
PUSH(88, test);
std::cout << test->data << std::endl;
}
I would expect the last line to print 88, but instead it prints 111. When I try to access the next element, I get a segfault so clearly I must be doing something wrong. Maybe I'm just tired, but hopefully one of you could shine some light on where I'm messing up, it seems correct to me.
void PUSH(T x, NODE<T> *S)
{
}
You are passing S by value, so any changes you make to S inside PUSH will not be visible outside.So even though you are adding elements to your stack, but your top remains the first node (111).
You can either pass a pointer to pointer to S or a reference to S
void PUSH(T x, NODE<T> **S)
{
NODE<T> *tmp = new NODE<T>;
tmp->data = x;
tmp->next = *S;
*S = tmp;
}

Access violation - cannot write to location

I am trying to write a code for a linked list but when I try to add a node the code gets stuck at the line immediately after the while loop in the add() function, reporting an access violation error. What's wrong?
#include<iostream>
template <class T>
class linkedlist
{
struct node
{
T data;
node *lp;
}*p;
public:
linkedlist();
void add(T t);
};
template<class T>
void linkedlist<T>::add(T t)
{
node *r,*q;
r = q = p;
while(p!= NULL)
{
q = p;
p = p->lp;
}
q->lp = new node;
q->lp->data = t;
p = r;
}
template<class T>
linkedlist<T>::linkedlist()
{
p = NULL;
}
int main()
{
linkedlist<int> l1;
l1.add(3);
}
You initialize p to NULL in the constructor, then try to dereference it in add (via q):
r = q = p;
// the while loop will not be executed as p == NULL
q->lp = new node;
You must initialize p first - either during construction (in which case your "empty" list won't be physically empty, so you must deal with this specifically, e.g. when iterating / removing elements), or you should check in add for the case when p == null and handle it differently.
Side note: p is supposed to point to your head element, so it is risky to use it also to iterate through the list in add, then restore its original value (stored in r). Why not simply leave it always intact, and use r for iterating? One less chance for bugs.
You should initialize the node in the constructor:
p = new Node;
Because here:
while(p!= NULL)
{
q = p;
p = p->lp;
}
q->lp = new node;
p is initially NULL, so q will also be NULL, ergo q->lp leads to undefined behavior and a crash.
Either initialize p or re-think your logic.

Mixing abstract classes and templates, a recipe for disaster?

I'm having problems with the following situation. I have three classes that are involved in this mixup. List, ListNode, City. I have a List<City *>, where the list will be made up of a set of ListNode<City *> (standard wrapper around the list nodes).
City is an abstract class, so there are several classes that inherit from it that could be placed in this list and accessed polymorphically. The List class has a getHead() method which returns a pointer to a ListNode that is the head.
Any city has a population, so to access the populations, I'd expect the following to work. It's not, thus my question. I broke it down into pieces to make it simpler along the way:
ListNode<City *> *head= country->city_list->getHead();
City *headnode = *head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
getPopulation() returns an integer. country is defined as List<City*> *city; Any help on how I could figure out my problem would be greatly appreciated.
edit adding more code for better idea of what I'm working with. First, ListNode:
template <class T>
class ListNode
{
public:
ListNode() {next = 0;node = 0;};
ListNode(T *t) {node = t; next = 0;};
ListNode(const ListNode &l)
{
//long copy constructor. snip.
};
T *getNode() const { return node; }
ListNode *getNext() const { return next; };
private:
T *node;
ListNode *next;
};
Now, here is what might relevant in the List class..
template <class T>
class List
{
public:
List()
{
head = 0;
size = 0;
};
List(ListNode<T> *t)
{
head = t;
size = 1;
};
List(T *t)
{
head = new ListNode<T>(t);
size = 1;
};
List(const List<T> &t)
{
// long copy constructor. snip.
};
//bunch of irrelevent methods.
ListNode<T> *getHead() const {return head;};
List &operator+=(T &t)
{
this->insert(&t);
size++;
return (*this);
};
private:
List &insert(T *t)
{
ListNode<T> *current = head;
if (current == 0)
{
head = new ListNode<T>(t);
}
else
{
while (current->getNext() != 0)
{
current = current->getNext();
}
current->setNext(new ListNode<T>(t));
}
return (*this);
};
ListNode<T> *head;
int size;
};
I have a hunch that the process of inserting might be the problem. I insert with the List class's += operator, shown in the List implementation above. It calls the private insert method shown above, as well. It looks like this:
City *somecity = new City(x,y,z); //some parameters. integers.
*city_list += somecity; // where city_list is a List.
I think you've got a variable scoping problem.
Your ListNode class contains a pointer to the node value. Your ListNode constructor takes in a pointer to the node value and saves it.
The problem is if that pointer is to a local variable that then goes out of scope. Your ListNode's node pointer is now pointing to an object that doesn't exist. e.g. in this example
addToList(List<int>& myList)
{
int x = 3;
myList += x; // pointer to x is in the list
}
// Out of scope; x no longer exists, but myList has a pointer to it.
// Accessing this node will result in an error.
There are a couple possible remedies:
Have your ListNode contain values rather than pointers. The drawback here is that you will be making copies of the values
Implement ListNode using a reference counted smart pointer which will manager the lifetime of the object.
Well, what you could do is:
ListNode<City *>* head = new ListNode<City*>(country->city_list->getHead());
City* headnode = head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
It will take the existing City (on the memory) and put it at the head of the List node, and so on.
and if you want to copy them, maybe you could just make this:
ListNode<City *>* head = new ListNode<City*>*(new City(country->city_list->getHead()));
City* headnode = new City(head->getNode());
cout << "Test: " << headnode->getPopulation() << endl;
Hope it will help you.