Segmentation fault in creating Linked list - c++

In this particular question I am trying to find the segmentation fault which is occurring. I know there is an error while creating a linked list of individual digits of K.
struct Node
{
int data;
struct Node *next;
};
int n1 = 0;
int n2 = 0;
int k = 1;
int calc(Node *h)
{
int sum=0;
for( ; h != NULL ; h = h->next)
sum=(sum*10)+h->data;
return sum;
}
Node* Lists(Node *headA, Node* headB)
{
n1 = calc(headA);
n2 = calc(headB);
int k = n1 + n2;
Node *temp;
temp->data=k%10;
while(k>0)
{
k=k/10;
Node *t1=new Node;
t1->data=k%10;
t1->next=temp;
temp=t1;
}
return temp;
}

The error resides in the following code:
Node *temp;
temp->data = k % 10;
Specifically, temp is declared to be a pointer that points to a Node struct, but it is never given a valid location in memory to point to, so it contains a garbage address that most likely refers to some non-writeable region.
If you wanted to fix this, you would first allocate a region for your variable, like this:
Node *temp = new Node;
and then mark it as released (by calling delete on it) later on when you were done with it. I would also recommend better formatting your code, as it's not exactly convenient to read from the viewer's perspective.

Related

Why am I getting this runtime error: member access within null pointer of type 'Solution::node' (solution.cpp)

I was solving a question on leetcode 1409. Queries on a Permutation With Key, but I am getting this runtime error I don't know why. I am unable to debug this error.
Problem Statement:Given the array queries of positive integers between 1 and m, you have to process all queries[i] (from i=0 to i=queries.length-1) according to the following rules:
In the beginning, you have the permutation P=[1,2,3,...,m].
For the current i, find the position of queries[i] in the permutation P (indexing from 0) and then move this at the beginning of the permutation P. Notice that the position of queries[i] in P is the result for queries[i].
Return an array containing the result for the given queries.
My approach: I created a linkedlist to store the integers form 1 to m.
Then according to each query, I pass it to a function getpos() which returns the position of that query in the list and then updates it as per the directions given in problem statement.
This return value is then added to a result vector which is supposed to be the final answer after all queries are processed.
I have added comments to better understand my code
class Solution {
public:
struct node {
int data;
node* next = NULL;
};
node* addnode(node* head, int data) {
if(head == NULL) {
head = new node;
head->data = data;
}
else {
node* temp = head;
while(temp->next != NULL) { temp = temp->next; }
temp->data = data;
}
return head;
}
int getpos(node** head, int data) { //To get position of given query
int count = 0;
node* temp = *head;
node* prev;
while(temp->data != data) { //runtime error:member access within null pointer of type 'Solution::node' (solution.cpp); SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:32:21
prev = temp;
temp = temp->next;
count++;
}
prev->next = temp->next; //searched node deleted
temp->next = *head; //add the searched node to beginning of the list
*head = temp; //udapate head
return count; //we have position stored in count;
}
vector<int> processQueries(vector<int>& queries, int m) {
node* head = NULL;
for(int i=0;i<m;i++) { head = addnode(head,i+1); }
int n = queries.size();
vector<int> result;
for(int i=0;i<n;i++) { result.push_back(getpos(&head,queries[i])); }
return result;
}
};
Please debug and explain the cause of the error. I face many runtime errors which I fail to debug.
Your add_node function is bugged. Just take a deep breath and look at the code. add_node should allocate a node using new every time it is called. Ask yourself how many times and under what circumstances your version allocates a new node?
I'm sure you can see that your code only allocates a new node when head equals NULL, therefore it must be bugged.
Incidentally if you wanted a linked list why didn't you use std::list? You would have avoided the mistake you made.

Error "Abort signal from abort(3) (sigabrt) " for linked list in C++

The following code is for a basic circular linked list, but when one inputs a large value for n(e.g 8 digits) it throws the "abort signal from abort(3) (sigabrt)" error. I'm not sure what it means and would love some guidance about fixing this with regard to my code.
Thank you!
#include<bits/stdc++.h>
using namespace std;
//First I created a structure for a node in a circular linked list
struct Node
{
int data;
struct Node *next;
};
// function to create a new node
Node *newNode(int data)
{
Node *temporary = new Node;
temporary->next = temporary;
temporary->data = data;
return temporary;
}
// This function finds the last man standing in
//the game of elimination
void gameOfElimination(int m, int n)
{
//first I created a circular linked list of the size which the user inputted
Node *head = newNode(1);
Node *prev = head;
//this loop links the previous node to the next node, and so on.
for (int index = 2; index <= n; index++)
{
prev->next = newNode(index);
prev = prev->next;
}
prev->next = head; //This connects the last and first nodes in our linked list together.
//when only one node is left, which is our answer:
Node *ptr1 = head, *ptr2 = head;
while (ptr1->next != ptr1)
{
int count = 1;
while (count != m)
{
ptr2 = ptr1;
ptr1 = ptr1->next;
count++;
}
/* Remove the m-th node */
ptr2->next = ptr1->next;
ptr1 = ptr2->next;
}
printf ("%d\n ",
ptr1->data);
}
//main program which takes in values and calls the function:
int main()
{
int n, p;
cin>>n>>p;
int m=p+1;
gameOfElimination(m, n);
return 0;
}
SIGABRT is generally issued when there are memory issues (heap corruption being quite common). In your code, I see only the new() operator being called, but you aren't deleting any unused nodes from your linked list! Seems like you're exhausting the memory allocated to your process.
You might be running out of memory. Check your ram usage during the execution of your program, that might lead to something.
enter code here
#include<bits/stdc++.h>
using namespace std;
class Node{
public:
int data;
Node *next;
};
void traverse(Node *head)
{
while (head != NULL)
{
/* code */
cout<<head->data<<"->";
head = head->next;
}
cout<<"NULL"
}
int main()
{
Node *head = new Node();
Node *second = new Node();;
Node *third = new Node();;
Node *fourth = new Node();;
head->data = 5;
head->next = second;
//cout<<head->data;
second->data=10;
second->next=third;
third->data = 15;
third->next = fourth;
fourth->data = 20;
fourth->next= NULL;
traverse(head);
return 0;
}```

Inserting Pop Functionality using link lists

I'm new to data structures and started using C++ after a long time. After going through a few diagrams, I decided to create my own linked list (implementing a simple pop function).
Here is the code I came up with:
#include <iostream>
using namespace std;
typedef struct node
{
int data;
node *next;
}node;
node *start;
int count_1 = 0;
void push(int x)
{
node *n = new node;
node *temp;
temp = n;
temp->data = x;
temp->next = start;
start = temp;
count_1++;
}
void ShowStack()
{
for (int i=0; i<count_1; i++)
{
node *temp = start;
cout<<temp->data<<endl;
temp = temp->next;
}
}
int main()
{
node *n = new node;
start = n;
n->data = 6;
n->next = NULL;
count_1++;
ShowStack();
push(7);
push(8);
push(9);
push(20);
//count_1=20;
ShowStack();
return 0;
}
It's very basic but I seem to be facing a problem; when I run the program the first output is '6' which is correct but after that, all the values are 20 (even if I hard-set the counter to some hard-coded value like 20 (see code). I'd appreciate if someone can explain what's wrong with this implementation (besides the fact that the program is very messy). Also, what steps would/should I take to get the correct 'pop' functionality.
In your ShowStack() function, move "node *temp = start;" outside the loop.

Copy constructor and destructor octree c++

I have created an Octree data structure but it's not perfect yet. I'm struggled with the copy constructor and the destructor.
Here is my header file:
class Octree
{
public:
static int lastbranch;
static bool utolsoelotti;
struct node
{
int value;
node *child[8];
};
Octree();
~Octree();
Octree(const Octree& oct);
void clear(node* node);
node* searchandset(int dec, int value);
node* search(int dec);
node* step(node *node, int k);
node* copy(node *n);
void Print(node *n)const;
void deletebranch(int branch);
node *root;
};
Constructor,destructor,copy contrsuctor
Octree::Octree()
{
root = new node;
root->value = 0;
for (int i = 0; i < 8; i++)
root->child[i] = 0;
}
Octree::~Octree()
{
clear(root);
}
Octree::Octree(const Octree& oct) {
root = copy(oct.root);
}
void Octree::clear(node *node){
for (int i = 0; i < 8; i++)
if (node->child[i])
clear(node->child[i]);
delete node;
}
Octree::node*Octree::copy(node *n) {
node* n2 = new node;
if (n) {
for (int i = 0; i < 8; i++) {
n2->child[i] = copy(n->child[i]);
}
}
return n2;
}
And here is how I created objects in the main:
int main() {
Octree tree;
Octree tree2(tree);
tree.searchandset(8, 2);
tree2.Print(tree2.search(8));
return 0;
}
In the searchandset function I'm giving a value for node number 8 at the first tree. After that I'm calling the copy constructor and print the 8th node of the second tree. The value is the same what I gave for the first tree, but when the desctructor called I always got this exception:
Exception thrown: read access violation.
node was 0xDDDDDDDD.
As I know it means that I tried to delete the nodes which I have already deleted. The object 'tree2' is a different object from 'tree' with the same values and nodes isn't it? Then I don't understand that exception above.
I'm new in c++ and I know it's basic stuff, so if somebody would direct me into the right direction I would very appreciate it.
The problem lies the in copy function. Let's go it through step by step:
node* n2 = new node;
if (n) {
for (int i = 0; i < 8; i++)
n2->child[i] = copy(n->child[i]);
}
return n2;
For an empty Octree oct, constructed with the default constructor, and copied to another Octree:
A new node is created, n2
n is the root of oct, so the condition if true
child[i] of n2 has a value of a copy of the corresponding child, so call copy again
A new node n2 is created
n is nullptr (because the children where all nullptr in oct), so don't execute condition
Return n2
Repeat steps 3 to 6 8 times
Return the root n2
Assign new pointer (n2) to root of the copied object
But wait! Did you notice that in step 6, you are returning a new pointer, even though the child is supposed to be nullptr!
That's the problem, because then, in clear, you will loop through each child. That's still ok, right? But then, you try to access the children, which are uninitialized (they have random value, the condition will evaluate to true), so you get a Read access violation, because it's not your memory.
So the solution? Only allocate memory for n2 if n is not nullptr.

segmentation fault when using pointer to pointer C++

I have been trying to use pointer to pointer to perform action something similar to inorder traversal in tree. here is my code
struct node {
char c = '\0';
int freq = 0;
node *left = NULL;
node *right = NULL;
string code = "";
};
void appendones(node **n) {
if ((*n) == NULL)
;
else {
(*n)->code += "1";
appendones(&(*n)->left);
appendones(&(*n)->right);
}
}
void combinenodes(node *a, node *b, node **n) {
appendones(&a);
appendones(&b);
//(*n)=newNode('\0',a->freq+b->freq);
(*n)->c = '\0';
(*n)->freq = a->freq + b->freq;
(*n)->left = a;
(*n)->right = b;
}
int main() {
N = input();
priority_queue<node, vector<node *>, compareNodefreq> nodefreq; // function object
for (int i = 0; i < N; i++) {
char s;
int freq;
cin >> s >> freq;
node *n = newNode(s, freq);
nodefreq.push(n);
}
// printheap(nodefreq);
// perform combining nodes based on frequencies
while (nodefreq.size() > 1) {
node *a = nodefreq.top();
nodefreq.pop();
node *b = nodefreq.top();
nodefreq.pop();
node *n;
combinenodes(a, b, &n);
nodefreq.push(n);
}
}
I get segmentation fault in (*n)->code+="1"; for appendone().
I am not able to figure out the error. My understanding is that I am passing
the pointer by reference and performing the appendzero() and appendone(),
so I guess there is no error in that part. Also my a and b in
combinenodes() cannot be null because I am popping from the stack.
Could you help me figure out?
Oh, I see it. In main()'s while loop, n is pushed and used later, but is invalid because the node object itself is never allocated in combinenodes() (currently commented out). The pointer value, then, is undefined, but in this case, turning out to be non-zero, defeating the safety check.