I'm trying out a basic program that will randomly initialize a linked list and print the value at a user-specified index (getnth). However, I'm running into a weird segmentation fault that appears when I comment out a specific cout line, and disappears when I uncomment it.
#include<iostream>
#include<cstdlib>
using namespace std;
struct node
{
int x;
node *next;
};
void ins(struct node*& headRef, int n)
{
node *newNode = new node;
if (!newNode)
return;
newNode->x = n;
if (!headRef)
newNode->next = NULL;
else
newNode->next = headRef;
headRef = newNode;
cout<<"\n"<<n<<" inserted at "<<headRef<<"\n\n";
}
void disp(struct node* head)
{
node *temp = head;
if (!temp)
{
cout<<"\n\nLL empty\n";
return;
}
while (temp)
{
cout<<temp->x<<" ";
temp = temp->next;
}
cout<<"\n\n";
}
void getnth(struct node* head, int n)
{
int i=0;
node *temp = head;
while (temp)
{
if (i == n)
{
cout<<"\n"<<temp->x<<"\n\n";
return;
}
}
cout<<"\nIndex too high\n";
}
int main()
{
node *head;
int i;
srand(time(NULL));
for (i=0; i<10; i++)
{
ins(head, rand()%10+1);
cout<<"Main head is "<<head<<"\n"; // segfault appears if this line is commented out, disappears if it's not
}
cout<<"\nInitial LL\n\n";
disp(head);
cout<<"\nEnter index ";
cin>>i;
getnth(head, i);
return 0;
}
In main initialize
node *head=NULL;
and your getnth is wrong , fix it.
May be something like this :-
void getnth(struct node* head, int n)
{
int i=0;
node *temp = head;
while (temp)
{
if (++i == n)
{
cout<<"\n"<<temp->x<<"\n\n";
return;
}
temp=temp->next;
}
cout<<"\nIndex too high\n";
}
By default, the pointer "head" in "main( )" is initialized with garbage, because it's automatic variable allocated on program stack.
So, when you pass the pointer "head" to the function "disp( )", this pointer is dereferenced and it causes segmentation fault.
You have to initialize the pointer "head" with 0 explicitly, and this will fix the problem.
Related
I am not getting how to run the concatenate function using both Node and LinkedList as classes. If anyone knows how to do it, please let me know.
Here I have created two classes one for linked list and the former one for Node creation.
Using create function and passing array as Linked list input. Also, I am getting the headref using getHead() and getHead2() functions which give the starting pointer of first and second Linked List respectively.
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node(){
data=0;
next=NULL;
}
Node(int data){
this->data=data;
this->next=NULL;
}
};
class LL{
Node* first, *second;
public:
LL(){
first=second=NULL;
}
void create(int arr[], int n){
Node* t, *last;
first=new Node();
first->data= arr[0];
first->next=NULL;
last=first;
for(int i=1;i<n;i++){
t=new Node();
t->data=arr[i];
t->next=NULL;
last->next=t;
last=t;
}
}
void create2(int arr[], int n){
Node* t, *last;
second=new Node();
second->data= arr[0];
second->next=NULL;
last=second;
for(int i=1;i<n;i++){
t=new Node();
t->data=arr[i];
t->next=NULL;
last->next=t;
last=t;
}
}
Node* getHead(){
return first;
}
Node* getHead2(){
return second;
}
void display(Node* p){
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void concatLL(){
Node* p=first;
while(p->next){
p=p->next;
}
p->next=second;
second=NULL;
}
};
int main()
{
LL l,l2;
int arr[]={1,2,3,4,5,6,7};
int arr2[]={2,5,7,8,9};
int n=sizeof(arr)/sizeof(arr[0]);
int n2=sizeof(arr2)/sizeof(arr2[0]);
l.create(arr,n);
l2.create2(arr2,n2);
cout<<"Displaying first LL"<<endl;
l.display(l.getHead());
cout<<"Displaying second LL"<<endl;
l2.display(l2.getHead2());
cout<<"Displaying Linked list after concatination"<<endl;
l.concatLL();
l.display(l.getHead());
return 0;
}
p is equal to NULL when executing p->next=second; in concatLL() causing undefined behaviour since the while loop runs until p == NULL. You should use while(p->next) instead of while(p) and check that first is not a null pointer before.
A linked list is still a Node, and as others said, at the end of your while loop p is pointed to NULL. You can't NULL->second=second neither NULL=second, so change your while loop stop condition:
void concatLL(){
Node* p=first;
while(p->next){
p=p->next;
}
p->next=second;
second=NULL;
}
};
Here is my solution:
#include <iostream>
using namespace std;
struct Node {
Node* next;
int value;
Node(int value) {
this->value = value;
this->next = NULL;
}
Node(int n, int a[]) {
value = a[0];
next = NULL;
Node* p = this;
for (int i = 1; i < n; i++) {
p->next = new Node(a[i]);
p = p->next;
}
}
void concat(Node* head) {
Node* p = this;
while (p->next != NULL) {
p = p->next;
}
p->next = head;
}
void display() {
Node* current = this;
while (current != nullptr) {
cout << current->value << " ";
current = current->next;
}
cout << endl;
}
};
int main() {
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 6, 7, 8, 9, 10 };
Node* list1 = new Node(5, a);
Node* list2 = new Node(5, b);
list1->display();
list2->display();
list1->concat(list2);
list1->display();
return 0;
}
this is the code
#include <iostream>
using namespace std;
struct Node{
int data;
Node *next;
};
Node *head;
`insert function takes a number as argument`
void insert(int a)
{
Node *temp = new Node();
temp -> data= a;
temp->next = head;
head = temp;
}
void print(void)
{
Node *temp1;
temp1 = head;
while(head != NULL)
{
cout<<temp1->data<<endl;
temp1 = temp1->next;
}
}
**main function**
int main()
{
head = NULL;
int a;
int b;
cout<<"how many elements do you want to insert";
cin>>b;
for (int i = 0;i < b; i++)
{
cout<<"enter a number"<<endl;
cin>>a;
insert(a);
print();
}
return 0;
}
when I enter the number to insert it shows program has stopped working. I am trying to insert numbers to linked list and print it ever time I add a number.I have checked for many other errors but it has none.
Looks like it might be due to an infinite loop like one of the comments says. Try updating the loop in the print function like this:
void print() {
Node *temp1;
temp1 = head;
// Here, I switched `head` with `temp1`
while (temp1 != nullptr) {
std::cout << temp1->data << std::endl;
temp1 = temp1->next;
}
}
I want to know what is the problem in creat_list2 function..
I have a problem in this code and as i knew it's in the creat_list2 cause the program run Successfully
when i stop this function it ask the user to enter a numbers that will be stored in the list 1 then print them but the problem as i saw is in the second fuction that creat the second list...,I have to submit my assignment tomorrow so I wish if any body can help me to solve this problem.
#include<iostream>
using namespace std;
struct node{
int x;
node *next;
};
struct snode{
int y;
snode *next;
};
creat_list1(node *&head, node *&tail)
{
int num;
cout<<"enter number\n";
cin>>num;
while(num!=0)
{
node *np=new node;
np->x=num;
if(head==nullptr)
head=np;
else
tail->next=np;
tail=np;
tail->next=nullptr;
cout<<"enter number again\n";
cin>>num;
}
}
creat_list2(node *&head, snode *shead, snode *stail)
{
int sum=0;
while(head!=nullptr)
{
for(int i=0;i<head->x;i++)
sum+=i;
snode *np= new snode;
np->y=sum;
if(head==0)
shead=np;
else
stail->next=np;
stail=np;
stail->next=nullptr;
}
head=head->next;
}
void print_list1 (node *head)
{
while(head!=nullptr)
{
cout<<head->x<<"\t";
head=head->next;
}
}
void print_list2(snode *shead)
{
while(shead!=nullptr)
{
cout<<shead->y<<"\t";
shead=shead->next;
}
}
main()
{
node *head=nullptr, *tail=nullptr;
snode *shead=nullptr, *stail=nullptr;
creat_list1(head,tail);
creat_list2(head,shead,stail);`enter code here`
print_list1(head);
print_list2(shead);
}
There are couple of issues with yours code,
creat_list2(node *&head, snode *shead, snode *stail) if u updated
head like head=head->next; it will reflect at the main.
shead and stail are just a local pointer and any update to just a pointer like stail=np;will not have any changes at the `main
There seems to be typo if(head==0) shead=np; instead it should be
if(shead==0) shead=np; which is causing null pointer exception.
I tried to fix the error at creat_list2 but functionality is still ambiguous to me,
void creat_list2(const node *head, node *&shead, node *&stail) //updated in argument
{
int sum = 0;
while (head != nullptr)
{
//for (int i = 0; i < head->x; i++)
// sum += i;
node *np = new node;
np->x = sum;
if (shead == 0) //error : head instead shead
shead = np;
else
stail->next = np;
stail = np;
stail->next = nullptr;
head = head->next;
}
}
I am trying to implement Linked List. In this sample program, user inputs an integer value (the number of strings to store in the list) and then strings one by one... But after several inputs (may be 4 or 5) the program crashes like the image here...
Even, I can't call any function more than 3 times at once which contains malloc() inside them..
I don't know why the problem is occurring. Help me fixing the issue....
#include <bits/stdc++.h>
using namespace std;
typedef struct Linked_List NODE;
struct Linked_List
{
string data;
NODE* next;
};
//Function prototypes
NODE *traverse(NODE *temp);
NODE* createNode(string data);
void preAppend(NODE* ln_list, string x);
NODE* find_data(NODE* ln_list, string data);
int main()
{
NODE* x=createNode("");
int t;
cin >>t;
string z;
while(t--)
{
cin >> z;
preAppend(x, z);
}
traverse(x);
return 0;
}
NODE *traverse(NODE *temp)
{
cout << temp->data << endl;
if(temp->next==NULL) return temp;
traverse(temp->next);
}
NODE* createNode(string data)
{
NODE* node = (NODE*)malloc(sizeof(NODE));
if(node==NULL)
{
printf("Error creating node (Error! Allocating Memory)\n");
exit(1);
}
node->data = data;
node->next = NULL;
}
void preAppend(NODE* ln_list, string x)
{
NODE* new_node = (NODE*)malloc(sizeof(NODE));
if(new_node==NULL)
{
printf("Error! Appending (Error Allocating Memory)\n");
exit(1);
}
new_node->data = x;
new_node->next = ln_list->next;
ln_list->next = new_node;
}
NODE* find_data(NODE* ln_list, string data)
{
NODE* current_node;
current_node = ln_list;
while(current_node->next!=NULL)
{
if(current_node->data == data)
{
return current_node;
}
current_node = current_node -> next ;
}
return NULL;
}
There are several problems in your code:
Usage of malloc instead of new
Using malloc for objects containing c++ objects (like stringin your case) won't call the constructors and therefore any operation upon the non constructed objects will fail.
If your program works without the return statements, it's because of undefined behaviour
Solution:
Replace
NODE* new_node = (NODE*)malloc(sizeof(NODE));
with
NODE* new_node = new NODE;
No return statements in non void functions
NODE *traverse(NODE *temp)
{
cout << temp->data << endl;
if (temp->next == NULL) return temp;
return traverse(temp->next); // return statement is needed here
}
NODE* createNode(string data)
{
NODE* node = new NODE;
if (node == NULL)
{
printf("Error creating node (Error! Allocating Memory)\n");
exit(1);
}
node->data = data;
node->next = NULL;
return node; // return statement needed here
}
Abuse of recursion
Using recursion in traverse may result in a stack overflow for long lists.
You should use a iterative approach. But you've found out that one already.
I uploaded the whole code at once. This method should work without any interruption
although if you want a complete understanding of each part i will recommend you to go over this article that i wrote on my website.
https://www.thebytewise.com/post/data-structure-and-algorithm-using-c-linear-linked-list-thebytewise
#include<stdio.h>
#include<stdlib.h>
void createList();
void traverseList();
struct node{
int data;
struct node *next;
}*header;
int main(){
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);
createList(n);
printf("\nData in the list:\n");
traverseList(n);
return 0;
}
void createList(int n){
struct node *newNode, *temp;
int data, i;
newNode = (struct node *) malloc(sizeof(struct node));
if(newNode == NULL){
printf("ERROR: Memory Overflow");
}
else{
printf("Enter element 1: ");
scanf("%d", &data);
newNode->data = data;
newNode->next = NULL;
header = newNode;
temp = newNode;
for(i=2;i<=n;++i){
newNode = (struct node *) malloc(sizeof(struct node));
if(newNode == NULL){
printf("ERROR: Memory Overflow");
}
else{
printf("Enter element %d: ",i);
scanf("%d",&data);
newNode->data = data;
newNode->next = NULL;
temp->next = newNode;
temp = temp->next;
}
}
}
}
void traverseList(int n){
struct node *temp;
int i;
if(header == NULL){
printf("ERROR: Memory Underflow");
}
else{
temp = header;
for(i=0;i<n;++i){
printf("\ndata %d= %d",i+1, temp->data);
temp = temp->next;
}
}
}
#include <iostream>
using namespace std;
int main()
{
struct node
{
int data;
node * next;
};
node * head;
node * n;
node * temp;
node * q;
int number;
cout << "Enter numbers";
cin >> number;
n = new node;
n->data = number;
head = n;
temp = n;
while (cin >> number)
{
while (number != -500)
{
n = new node;
n->data = number;
temp->next = n;
temp = n;
}
}
while (head != NULL)
{
cout << head->data;
head = head->next;
}
}
I don't understand why this would not work. The program creates a new node then sets whatever the user entered equivalent to the variable data of that new node then it makes head and temp point to the new node. Then it gets the users second input and compares it to -500 and if it evaluates as true it creates a new node puts the data of the second input into the variable data then it links the first node and second node together then it makes temp point to the second node. If the condition of the 2nd while loop is false it goes to the third which is where it is suppose to print the list.
Who sets the last node's next to NULL?
At n = new node; n->next is not NULL but undefined, in Debug versions usually it is 0xcccccccc or something similar value to make it visible that it is not initialized. If you try to dereference it, you will get an access violation.
while (cin >> number) { // this loop is endless, because you can always read the user input data (unless some exception happen)
while (number != -500)
{
n = new node; // you already have data allocated. no need to allocate it once more
n->data = number;
temp->next = n;
temp = n;
// as was already mentioned: set n->next to NULL
} }
if you want to break after you checked that the number is not -500, then you can do the following instead:
while (cin >> number) {
if (number != -500) { ...; // do your stuff
break;
}
}
And, by the way, you have a memory leak. If you use flat C pointers then consider delete operator to clear your memory. For that purpose, you need to know where your list starts(basically, head) and iterate through a whole list invoking delete node.
Please, also consider, that it is a bad code style to write something like:
while (cin >> number)
You can also try this-
This code makes a linked list on user input and printlinkedlist (function) print the linked list created.
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
node* next;
};
void printlinkedlist(node* node)
{
int c=0; //taken just for good looking output
while(node!=NULL)
{
if(c>0)
{
cout<<"->"<<node->data;
node = node->next;
}
else
{
cout<<node->data;
node = node->next;
c++;
}
}
}
int main() {
int n;
cout<<"Enter no. of nodes=";
cin>>n; //User enters number of nodes he want.
int num,c=0; //initialized c for setting head with second node..
node* head = new node; //initialized head node
node * temp = new node; //initialized temp node
cin>>num;
head->data=num;
for(int i=2;i<=n;i++)
{
if(c==0)
{
cin>>num;
temp->data=num;
head->next=temp; //head point to second node i.e. temp
c++;
}
else
{
cin>>num;
node * temp1 = new node; //initialize other temp node for every value
temp1->data=num;
temp->next=temp1; //point to temp1 to temp
temp=temp1; //set temp as temp1
}
}
printlinkedlist(head);
}
#include<iostream>
using namespace std;
class node{
public:
int data;
node* next;
};
// a function to create linked list passing pointer to pinter
void create_list(node**head)
{
int num;//num is the data
cin>>num ;
node*new_node=new node();//
new_node->data=num;
new_node->next=NULL;
node*temp;
if(*head==NULL)
{
*head=temp=new_node;
}
else{
temp->next=new_node;
temp=new_node;
}
}
void print_list(node* head)
{
if(head == NULL)
{
cout<<"empty list"<<endl;
}
node *ptr = NULL;
ptr=head;
cout<<"data in the list: "<<endl;
while(ptr!=0)
{
cout<<ptr->data<<endl;
ptr=ptr->next;
}
}
int main()
{
int n,i; //
cout<<"enter the number of nodes:"<<endl;
cin>>n;
cout<<"enter data as num:"<<endl;
node* head=NULL;
for(i=0;i<n;i++)
{
create_list(&head);//passing the address of head
}
print_list(head);
return 0;
}