How to fix 'Segmentation fault' error in c++ - c++

I'm trying to learn how to use the gdb debugger to fix this sample code. When stepping through the debugger, I can see that the line 'mylist[i]->val = i;' is throwing the segmentation fault.
I think I understand what a segmentation fault is, but I don't understand how this line could be causing it. Do I need to allocate memory for the mylist vector? How would I do that? I thought that the vector was already initialized and ready in main(), but I'm not really sure.
I have tried using 'new' for each node in the mylist vector but that gave me a compile error.
node* mylist[i] = new node; //what I tried
mylist[i]->val = i;
mylist[i]->next = NULL;
//error message
error: array must be initialized with a brace-enclosed initializer
node* mylist[i] = new node;
My code
class node
{
public:
int val;
node* next;
};
void create_LL(vector<node*>& mylist, int node_num)
{
mylist.assign(node_num, NULL);
//create a set of nodes
for (int i = 0; i < node_num; i++)
{
mylist[i]->val = i; //error happens here
mylist[i]->next = NULL;
}
... (relevant section of main() below)
int main(int argc, char ** argv)
{
const int NODE_NUM = 3;
vector<node*> mylist;
create_LL(mylist, NODE_NUM);
The actual error shown is "Segmentation fault (core dumped)"
When I print mylist right before the error line it shows
$1 = std::vector of length 3, capacity 3 = {0x0, 0x0, 0x0}
I am still learning c++ so I might be missing something really basic.
I would really appreciate any help. Thanks!

For starters, it's better if you hide variables inside a class. If you're not going to, the convention is to use a struct. It's also good practice to provide some constructor in that case, and maybe with default values:
class node
{
int val;
node* next;
public:
node(int v= 0, node* n= nullptr) : val(v), next(n) {}
};
Note the use of nullptr instead of NULL. Using the latter is a bad practice in c++.
The problem is that you can't use positions on a std::vector if they have not been allocated. When you do mylist[i]->val = i; you're in the lands of undefined behaviour.
You need first to push_back() or emplace_back() into a std::vector. So it's size() grows as it puts your data at the end (the back) of the vector. You could also use other methods, like reserve(). While push_back() pushes node* elements on your list, emplace_back() would construct them in place with no copy (no difference with raw pointers, but you can use a vector<node> instead of vector<node*> which is more straightforward.
// create a set of nodes
void create_LL(vector<node>& mylist, int node_num)
{
for (int i = 0; i < node_num; i++) {
mylist.emplace_back(i, nullptr); // calls node::node(i, nullptr) and inserts it at the end of the vector
}
or
// create a set of nodes
void create_LL(vector<node*>& mylist, int node_num)
{
for (int i = 0; i < node_num; i++) {
mylist.emplace_back(new node(i, nullptr));
}

Related

does dynamically allocation structs in cpp require redefining elements?

Trying to implement the add function in dynamic list, recursively.
The code is self-explanatory:
struct list {
int value;
list* next = NULL; // is this valid?
};
list head;
void add(list* cur, int value) {
if (cur->next) {
add(cur->next, value);
return;
}
cur->next = (list*)(malloc(sizeof(list)));
cur->next->value = value;
cur->next->next = NULL; // withouth this line, the program errors out after two calls to the function add
}
int main() {
for (int i = 0; i < 50; i++)
add(&head, i);
}
After seeing the debugger, I realized that calling malloc wasn't initiating "next" with NULL as specified in the defininition of the list struct.
As noted in comments, malloc does not initialize anything. It simply grabs a chunk of memory big enough for a list struct. Now, that might mean that struct has next set to NULL, or it might not.
That is why you're having to explicitly initialize it to NULL as that prevents undefined behavior when accessing that member.
If you use new to handle dynamic memory allocation, then the next member is initialized to NULL.
cur->next = new list;
Including this use of malloc, your code is very C-ish, and there are numerous improvements C++ will allow you to make.

What If I Put All Nodes of LinkedList into an Array?

So lately I've been learning C++, and I am studying Linkedlist now.
I am wondering why don't we create Nodes with an array, let's say:
#include <iostream>
using namespace std;
struct Node {
int data = 0; //data
Node* next = nullptr; //next node in the linked list;
};
void deallocateLinkedList(Node* n)
{
if (n == nullptr) // An empty list; nothing to delete
return;
else{
deallocateLinkedList(n->next);
delete n;
n = nullptr;
}
}
int main()
{
int k;
cout<<"enter k as number of nodes"<<endl;
cin>>k;
Node* n = new Node [k]; //creates dynamic array;
for(int i =0;i<k;i++)
{
if (i==k-1)
{
n[i].data=i;
n[i].next=nullptr;
}
else
{
n[i].data=i;
n[i].next = &n[i+1];
}
}
deallocateLinkedList(n); //pointer points to the first node;
cout<<"programmed finished"<<endl; //indicates successful running
return 0;
}
In this case, the Nodes are linked and also put into an array;
However, the deallocate programme doesn't run completely and exit without error
Is there any problem with this style of creating Linked List or just the deallocation problem?
What If I Put All Nodes of LinkedList into an Array?
Then that's where the nodes are.
However, the deallocate programme doesn't run completely and exit without error
Is there any problem with this
Yes, there is a problem.
The problem is that you may only pass a pointer to delete if you got the pointer from new (and it must be deleted at most once, and if you created an array, then you must use delete[]).
When you do delete n;, you'll find that you never assigned any of n->next (which will be the n in the recursive call) to have a pointer value that was returned from new. As a consequence, the behaviour of the program is undefined.
If you allocate objects like this:
Node* n = new Node [k];
then you must deallocate like this:
delete[] n;

Segmentation fault, when compiled with cmake and without cout

I'm trying to make a list of objects (not using std::list) containing a pointer to the next and previous objects. For some reason the following code is throwing a segmentation fault, but when I commented out std::cout the code won't throw a segmentation fault, and when I don't compile with cmake, but with clang++. In both cases I'm using C++14.
#include <iostream>
class myListElement
{
myListElement *next;
double val;
public:
myListElement(int entry, myListElement *newPrev):val(entry), prev(newPrev){}
void setNext(myListElement *newPrev){prev = newPrev;}
};
class myList
{
myListElement *first,*last;
public:
myList(){}
~myList(){}
void push_back(int entry)
{
myListElement temp(entry,last);
if(last != nullptr)
{
last->setNext(&temp);
}
}
};
int main()
{
int n = 1000;
myList my_list;
//std::cout << "\ntest";
for(int i = 0; i < n; ++i)
{
my_list.push_back(i+1);
}
}
How can that be the case?
I'm sorry for the long code, but I couldn't find any part to delete without getting the Segmentation fault and keeping the sense of the program.
Thank you for every bit of help!
You do not initialize first and last with nullptr in the constructor.
You store pointers to local objects temp, their life is limited by push_back exit. You got dangling pointers and UB.
That is why STL exists and must be used. It is developed by the best C++ professionals and well tested.

C++ object pointer scope

I started writing a binary tree and then came up with this example and I'm not sure what's going on. So here's the code:
#include<iostream>
using namespace std;
struct Node
{
Node *left, *right;
int key;
Node()
{
left = NULL;
right = NULL;
key = 0;
}
Node(int key)
{
left = NULL;
right = NULL;
key = key;
}
};
struct Tree
{
Node* root;
void Add(int k)
{
Node* t;
t->key = k;
root->left = t;
}
Tree(int key)
{
this->root = new Node(key);
}
};
int main()
{
Tree* tree = new Tree(5);
tree->Add(4);
cout<<tree->root->left->key;
return 0;
}
Add function Add in Tree is whats confuses me. So, there is a pointer to Node object, but new keyword is not used and it appears to me that anyway there is memory allocated in the heap because I can reach the object. Shouldn't go out of scope and be destroyed? And why I can reach that object and print out its key?
Probably that memory belongs to your program and nothing bad seems to happen because you are using so little memory. If you use more memory, some object will own that unallocated space and expect it to remain unmodified. Then this code will start giving you problems.
You are "dereferencing an uninitilized pointer". There are questions relating to this here and here, for instance. Your compiler may blow up if you do this, or it may not: the behaviour is undefined. Anything might happen, including the appearance that things are working.
Use new, like you should.
This line …
Node* t;
… is like:
Node* t = random_address;
It means that the next line …
t->key = k;
… is able to corrupt interesting memory locations.
The code is invalid. In this function
void Add(int k)
{
Node* t;
t->key = k;
root->left = t;
}
local variable t is not initialized and has indeterminate value. So the execution of the statement
t->key = k;
results in undefined behaviour.
You correctly pointed to that there must be used operator new. For example
Node* t = new Node( k );
Nevertheless even in this case the function is invalid because it has to check whether the new key is less of greater than the key of root. Depending on the condition there should be either
root->left = t;
or
root->right = t;

C++ Free Heap block 3da9e0 modified at 3daa08 after it was freed

I've seen the some solutions to this in this website but none of them solved my problem.
I'm implementing an n-children, unbalanced tree type and the add operation gives me an exception.
The code is as follows:
struct Node {
// Just to initialize the parent node to zero, default constructor
Node(Node *parent = 0) : m_parent(parent) {
}
Node *m_parent;
vector<Node *> m_children;
GameBoard m_currentBoard;
};
Where the error is happening:
Node *tempNode = 0;
// Going through each of them to create new nodes
for (unsigned int i = 0; i < availableBoards.size() ; i++) {
// Create a new node
tempNode = new Node;
tempNode->m_parent = curNode;
tempNode->m_currentBoard.setBoard(availableBoards[i]);
// This is the line when program crashes
curNode->m_children.push_back(tempNode);
}
I have also tried declaring the tempNode inside the loop but it didn't help either.
I've checked through the watch from Visual Studio, curNode isn't NULL nor the tempNode.
Why am I getting this error?
Thanks for your answers.
OK the problem was destroying the object that was running the second code segment even before calling it. It was something like follows:
class A{
int *getAsdf();
int *asdf;
}
int main() {
A *newObj = new A;
delete newObj;
newObj->getAsdf();
}
I don't have a single clue as to how a method is called from an object that was deleted before. Error happened inside a function like getAsdf and even the parameters were valid. Can some-one explain?