c++ segmentation fault in linkedlist [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I created a program for my homework that deals with linked lists. It ran fine before i entered a number and then it crashed on me giving me a segmentation fault error.
I know what that means but i cannot find the the issue.
Take a look and see if you could help me out! Thanks!
#include <iostream>
using namespace std;
struct node //node structure
{
int number;
node *next;
};
bool isempty(node *head);
char menu();
void first(node *&head, node *&last, int number );
void insert(node *&head, node *&last, int number);
void remove(node *&head, node *&last);
void shownode(node *current);
bool isempty(node *head)
{
if(head = NULL)
return true;
else
return false;
}
char menu()
{
char choice;
cout<<"choose and option:"<<endl;
cout<<"1. Add Node."<<endl;
cout<<"2. Remove Node."<<endl;
cout<<"3. Show Node List."<<endl;
cout<<"4. Exit Program."<<endl;
cin>>choice;
return choice;
}
void first(node *&head, node *&last, int number ) //adding first
{
node *temp =new node;
temp->number = number;
temp->next = NULL;
head = temp;
last = temp;
}
void insert(node *&head, node *&last, int number)//adding more
{
if(isempty(head))
first(head, last, number);
else
{
node *temp =new node;
temp->number = number;
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void remove(node *&head, node *&last)//destructor
{
if(isempty(head))
cout<<"List is empty."<<endl;
else if (head == last)
{
delete head;
head == NULL;
last == NULL;
}
else
{
node *temp = head;
head = head->next;
delete temp;
}
}
void shownode(node *current)
{
if (isempty(current))
cout<<"list is empty"<<endl;
else
{
cout<<"Nodes in list:"<<endl;
while(current != NULL)
{
cout<<current->number<<endl;
current = current->next;
}
}
}
int main()
{
node *head = NULL;
node *last = NULL;
char choice;
int number;
do{
choice = menu();
switch(choice)
{
case '1': cout<<"inert number:"<<endl;
cin>>number;
insert(head, last, number);
break;
case '2': remove(head, last);
break;
case '3': shownode(head);
break;
default: cout<<"Exit";
}
}while(choice != '4');
return 0;
}
This is the error i got:
choose and option:
1. Add Node.
2. Remove Node.
3. Show Node List.
4. Exit Program.
1
inert number:
44
RUN FINISHED; Segmentation fault: 11; real time: 2s; user: 0ms; system: 0ms

First, this line of code,
if(head = NULL)
should be,
if(head == NULL)

No idea if you are misunderstanding '=' and '==', '=' for assign value and '==' judge if equal.
In bool isempty(node *head) function
if(head = NULL) => if (head == NULL)
In remove(node *&head, node *&last) function
else if (head == last)
{
delete head;
head == NULL;
last == NULL;
}
should be
else if (head == last)
{
delete head;
head = NULL;
last = NULL;
}

Related

I'm trying to implement a binary tree. My program stops abruptly after a few node insertions. What is going wrong?

I'm just trying out implementation of binary tree. It's not for a college class so I cannot ask a teacher :(
I have tried debugging it with the Codeblocks debugger but I'm still not understanding what is going wrong.
I am using class instead of struct. Currently I have only implemented insertion and inorder traversal functions.
For insertion function, I am checking if the root node is NULL or not. If it is NULL, the newNode becomes equal to the root node. Or else, I find the appropriate parent node and then append the newNode as its child.
And, in the inorder traversal function, is my recursion correct?
Edit: Turns out that I wasn't initializing my Node variables. My code is working after initializing those variables. Thanks for your help!
#include<iostream>
using namespace std;
class Node
{
public:
int data;
Node* left_child;
Node* right_child;
};
Node* root = NULL;
void insertion();
void inorder_travesal(Node*);
int main(){
char ch;
do{
int choice;
cout<<"\nEnter your choice: \n1. Insertion\n2. Inorder Traversal\n : ";
cin>>choice;
switch(choice){
case 1: insertion();
break;
case 2: inorder_travesal(root);
break;
}
cout<<"\nDo you want to continue?: ";
cin>>ch;
}while(ch == 'y');
return 0;
}
void insertion(){
int data;
cout<<"\nEnter data: ";
cin>>data;
Node* newNode = new Node;
newNode->data = data;
if(root == NULL)
{
root = newNode;
return;
}
else
{
Node* temp = root;
while(true){
if(temp->data > newNode->data)
{
if(temp->left_child == NULL)
{
temp->left_child = newNode;
return;
}
else
{
temp = temp->left_child;
}
}
else
{
if(temp->right_child == NULL)
{
temp->right_child = newNode;
return;
}
else
{
temp = temp->right_child;
}
}
}
}
inorder_travesal(root);
}
void inorder_travesal(Node* temp){
if(temp->left_child != NULL){
inorder_travesal(temp->left_child);
}
cout<<temp->data<<" ";
if(temp->right_child != NULL){
inorder_travesal(temp->right_child);
}
}

How do I remove these nodes from a linked list?

When I run the code, it will not remove the nodes like I want it to. They stay on the list. I think that there may be issues with the .cpp and header file, but I am not sure. This is my first time messing with Linked Lists, so any help would be appreciated! Code:
#include <iostream>
#include "NumberList.cpp"
using namespace std;
int node(){
int i,j;
char answer;
NumberList list; //create a new linked list
bool MainMenu = true;
while (MainMenu){
cout<<"Please make a selection:\n1.Add a starting point\n2.Remove a starting point.\n3.Quit"<<endl;
cin>>answer;
if(answer == '1'){
bool keepGoing = true;
while (keepGoing){
cout<<"Enter the row: ";
cin>>i;
cout<<"Enter the column: ";
cin>>j;
list.add(i,j);
cout<<"You added "<<i<<"and "<<j<<endl;
//list.add(4,5);
//list.add(3,6);
cout<<"Here is the list: "<<endl;
list.displayList();
cout<<"Would you like to add another point? y/n"<<endl;
cin>>answer;
if (answer == 'y')
{
keepGoing=true;
}
else if (answer == 'n')
{
keepGoing=false;
}//end else
}
}
else if (answer == '2'){
int x,y;
cout<<"Here are the points chosen: "<<endl;
list.displayList();
cout<<"Which point do you want to remove?\nRow: "<<endl;
cin>>x;
cout<<"Column: "<<endl;
cin>>y;
list.remove(x,y);
cout<<"Updated list: "<<endl;
list.displayList();
}
else if (answer == '3'){
MainMenu = false;
}//end else if
else{
cout<<"Unable to process"<<endl;
}
}//end keepGoing
}
int main()
{
node();
}
NumberList.cpp:
#include "NumberList.h"
using namespace std;
void NumberList::add(int i, int j)
{
if (head == NULL)
head = new ListNode(i,j);
else
{
//The node is not empty. Use nodePtr to traverse the list
ListNode *nodePtr = head;
while (nodePtr->next != NULL)
nodePtr = nodePtr->next;
//nodePtr->next is NULL so nodePtr points to the last node.
//Create a new node and put it after the last node
nodePtr->next = new ListNode(i,j);
}
}
void NumberList::displayList()
{
ListNode *nodePtr = head; //Start at head of the list
while(nodePtr)
{
//Print the value in the current node
cout<<"("<<nodePtr->i<<","<<nodePtr->j<<")";
//Move onto the next node
nodePtr = nodePtr -> next;
}
}
void NumberList::remove(int x, int y)
{
ListNode *nodePtr, *previousNodePtr;
//if the list is empty, do nothing;
if (!head) {
cout<<"The list is empty"<<endl;
return;
}
//int i,j;
int j;
//Determine if the first node is the one to delete.
if (head-> i&&j == x&&y)
{
nodePtr = head;
head = head ->next;
delete nodePtr;
}
else
{
//Initialize notePtr to the head of the list;
nodePtr = head;
//Skip the nodes whose value member is not number
while(nodePtr != NULL && nodePtr-> i&&j != x&&y)
{
previousNodePtr = nodePtr;
nodePtr = nodePtr->next;
}
//Link the previous node to the next node after
// nodePtr, then delete nodePtr
if (nodePtr)
{
previousNodePtr -> next = nodePtr->next;
delete nodePtr;
}
}
}
NumberList.h:
#include <iostream>
using namespace std;
class NumberList
{
protected:
//Declare a class for the list node.
struct ListNode
{
int i,j;
ListNode *next;
ListNode(int i1, int j1, ListNode *next1=NULL)
{
i=i1;
j=j1;
next=next1;
}
};
ListNode *head;//List head pointer
public:
NumberList(){head=NULL;}
//~NumberList();
void add(int i, int j);
void remove(int i, int j);
void displayList();
};
Needed to add the method call with the structure pointer operator on both sides of the and sign. Instead of:
if (head-> i&&j == x&&y)
Did this:
if (head-> i==x && head->j==y)

delete a node at nth position IN C++

I am having problems deleting from an arbitrary position given in a linked list. I succeeded for the first position and last position of my list but got a runtime error when going for the nth position.
struct node
{
int number;
node *next;
};
struct Box
{
void insertAsFirstElement(node *&head, node *&last,int number);
void insert(node *&head, node *&last,int number);
void remove(node *&head, node *&last);
void showList(node *current);
};
bool isEmpty(node *head) {
return head == NULL;
}
char menu() {
char choice;
cout<<"Menu"<<"1. Add an item.\n"<<"2. Remove an item.\n"<<"3. Show the list.\n"<<"Exit\n";
cin >> choice;
return choice;
}
void insertAsFirstElement(node *&head, node *&last,int number) {
node *temp = new node;
temp->number = number;
temp->next = NULL;
head = temp;
last = temp;
}
void insert(node *&head, node *&last,int number) {
if(isEmpty(head))
insertAsFirstElement(head, last, number);
else {
node *temp = new node;
temp->number = number;
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void remove(node *&head, node *&last,int number) {
cin>>number;
node *temp = new node;
if(isEmpty(head))
cout<< "this list is already empty.\n";
else if (head == last) {
delete head;
head = NULL;
last = NULL;
} else {
for(int i = 0; 1< number-2; i++)
/*node *temp = head;
head = head->next;
delete temp;*/
node *temp = head;
head = head->next;
temp= temp->next;
node* temp2 = temp->next;
temp->next = temp2->next;
delete temp2;
}
}
void showList(node *current) {
if(isEmpty(current))
cout << "The list is empty\n";
else {
cout << "The list contains:\n";
while(current != NULL) {
cout << current->number << endl;
current = current->next;
}
}
}
int main() {
node *head = NULL;
node *last = NULL;
char choice;
int number;
do{
choice = menu();
switch (choice) {
case'1':
cout << "please enter a number: ";
cin >> number;
insert (head,last,number);
break;
case'2':
remove(head,last,number);
break;
case '3':
showList(head);
break;
default:
cout<< "System exit\n";
}
}while (choice !='4');
}
Your loop condition in the removal function is wrong, it's not checking anything affected by the loop, so it would just run forever (or more likely, until it breaks something).
In addition, your remove is not matching its signature. Since you didn't really explain what you want it to do, it's hard to say how to fix it - is number the value you want to remove (what if there are multiple ones?) is it the index to remove? is it a number of elements to remove?
I'll assume it's the second, as it seems like what you were trying to do. In any cases you need to search for that item before deleting it, so instead of -
for(int i = 0; 1< number-2; i++)
try
for(int i = 0; i < number-1; i++)
The 1 was probably a typo, and it's enough to stop one element ahead (the index meaning is up to you, but if the head is 0, then deleting index 2 should run the loop once)
Then, you need to put some brackets around your loop, since right now you're only looping over the first line of code. Move the assignment of temp = head ahead of the loop, you only need to do it once, and loop over
temp= temp->next;
(if that's your only line you don't need brackets, but it's a good habit anyway).
That should bring you to the element ahead of your index. If that's the head, you need some special treatment, but otherwise don't change head, or you'll lose elements you want to keep.
The actual removal looks like it might work, but everytime you dereference next, you need to make sure it's not NULL.

Linked List issue insert from middle C++

I am new to linked lists, and now I face a problem on how to add the node into the middle of a list. Example like if I got a name list show below and when I add data one by one just like below sequence:
1.andrew
2.eric
3.madness
4.gerik
I want my data "gerik" in "madness" place when it show out. I am able to sort the data infront of "eric" but after "eric" i am not idea. I want my output just like below:
1.andrew
2.eric
3.gerik
4.madness
Below will be my example code, please help me by giving me advise or code sample:
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
using namespace std;
struct node
{
char f_name[20];
char l_name[20];
char u_id[10];
node *next;
};
node *head;
node *curr;
//prototype
void display();
void add();
void search_name();
void insert_data(node *tempnode);
void insert_before_head(node *tempnode);
void menu(char choice);
char pause;
//function start...
void search_name()
{
char name[20];
curr = head;
cin.ignore(30,'\n');
cout<<"Key In Last Name :"<<endl;
cin.get(name, 20);
cin.ignore(30,'\n');
while((curr->next != NULL) && (strcmp(curr->l_name, name) != 0))
{
curr = curr->next;
}
if(curr != NULL)
{
cout<<"Record Found !"<<endl;
cout<<"First Name"<<setw(16)<<"Last Name"<<setw(16)<<"User ID"<<endl;
cout<<"--------------------------------------------------------------"<<endl;
cout<<curr->f_name<<setw(20)<<curr->l_name<<setw(16)<<curr->u_id<<endl<<endl;
}
else
{
cout<<"No Match !"<<endl;
cout<<"Press 'Enter' To Continue"<<endl;
cin.get(pause = getch());
system("cls");
}
};
void display()
{
curr = head;
if(head != NULL)
{
cout<<"First Name"<<setw(16)<<"Last Name"<<setw(16)<<"User ID"<<endl;
cout<<"--------------------------------------------------------------"<<endl;
while(curr != NULL)
{
cout<<curr->f_name<<setw(20)<<curr->l_name<<setw(16)<<curr->u_id<<endl;
curr = curr->next;
}
}
else
{
cout<<"No Data. File storage Empty!"<<endl;
}
};
void add()
{
node *temp;
temp = new node;
cin.ignore(30, '\n');
cout<<"Key In First Name:"<<endl;
cin.get(temp->f_name, 20);
cin.ignore(30, '\n');
cout<<"Key In Last Name:"<<endl;
cin.get(temp->l_name, 20);
cin.ignore(30, '\n');
cout<<"Key In Your ID:"<<endl;
cin.get(temp->u_id, 10);
insert_data(temp);
};
void insert_data(node *tempnode)
{
node *temp;
if(head == NULL)
{
node *temp;
temp = new node;
temp = head;
tempnode->next = NULL;
head = tempnode;
}
else if(strcmp(tempnode->l_name, head->l_name) < 0)
{
insert_before_head(tempnode);
}
else
{
temp = new node;
curr = head;
while(curr->next != NULL)
{
curr = curr->next;
}
temp = tempnode;
curr->next = tempnode;
tempnode->next = NULL;
}
};
void insert_before_head(node *tempnode)
{
node *temp;
if(head != NULL)
{
temp = new node;
temp = tempnode;
tempnode->next = head;
head = tempnode;
}
};
void menu(int choice)
{
switch (choice)
{
case 1 :
add();
break;
case 2:
display();
break;
case 3:
search_name();
break;
case 4:
cout<<"Exit Program !"<<endl;
break;
default :
cout<<"Error! Program Terminate !"<<endl;
}
};
int main()
{
int choice;
node *temp;
head = NULL;
curr = NULL;
cout << "Data Stack Head And Any Position !" << endl;
system("cls");
do{
cout<<"1. Add Data."<<endl;
cout<<"2. Show Data. "<<endl;
cout<<"3. Search Last Name "<<endl;
cout<<"4. Exit. "<<endl;
cin >>choice;
menu(choice);
}while(choice != 4);
return 0;
}
To sort linked lists you need to use the divide and conquer strategy with merge sort.
In order to insert in the middle you need to create 2 nodes Node slow and Node fast. At first Node slow is head.next, Node fast is head.next.next and you keep moving those 2 by doing slow = slow.next and fast = fast.next.next, until you hit the end with Node fast. If you think about it, fast will be moving twice as fast as Node slow, so in the end Node slow will be in the middle. Then insert after that node.
We want to insert in our list newNode.
Let node X be the node, after which newNode should be inserted to preserve sorting order.
You can rewite your insert_data(...) function like in my example.
I took the code, sugested by WhozCraug and rewrote it to be more evident.
void insert_data(node *newNode)
{
node **pointerToTheNextPtr = &head;
// find position to insert new node
while (*pointerToTheNextPtr && strcmp((*pointerToTheNextPtr)->l_name, newNode->l_name) < 0)
pointerToTheNextPtr = &((*pointerToTheNextPtr)->next);
// here pointerToTheNextPtr stores the pointer to the X->next field
// insert new node between X and *(X->next)
newNode->next = *pointerToTheNextPtr; // set newNode->next = X->next
*pointerToTheNextPtr = newNode; // set X->next = newNode
}

Adding/ removing tail, showing list in reverse. linked list c++

I am working on a linked list, I made a menu (As a noob this greatly impressed me:)) and got the add front and remove front to work. although I want to be able to add in a node at the end then remove it and display it in reverse. I thought my removelast function looks like it would work but it doesn't. Not sure how to add to the tail, and no clue what so ever how to show in reverse. I looked up some guides but i am no good at understanding from text, I like to see examples pertaining to my problem.
Take a look!
#include <iostream>
using namespace std;
struct node //node structure
{
int number;
node *next;
};
bool isempty(node *head);
char menu();
void first(node *&head, node *&last, int number );
void insert(node *&head, node *&last, int number);
void removefirst(node *&head, node *&last);
void removelast(node *&head, node *&last);
void shownode(node *current);
void showreverse(node *&last);
bool isempty(node *head)
{
if(head == NULL)
return true;
else
return false;
}
char menu()
// I added a menu because in an actual application this is what you would have
//And it was fun :D
{
char choice;
cout<<"choose an option:"<<endl;
cout<<"1. Add Node."<<endl;
cout<<"2. Add Node to Last"<<endl
cout<<"3. Remove First Node."<<endl;
cout<<"4. Remove last node"<<endl;
cout<<"5. Show Node List."<<endl;
cout<<"6. Reverse Node List."<<endl;
cout<<endl;
cin>>choice;
cout<<endl;
return choice;
}
void first(node *&head, node *&last, int number ) //adding first
{
node *temp =new node;
temp->number = number;
temp->next = NULL;
head = temp;
last = temp;
}
void insert(node *&head, node *&last, int number)//adding more
{
if(isempty(head))
first(head, last, number);
else
{
node *temp =new node;
temp->number = number;
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void addlast (node *&head, node *&last, int number)
{
node *temp =new node;
temp->number = number;
temp->last = NULL;
last->next = temp;
last = temp;
}
void removefirst(node *&head, node *&last)//destructor
{
if(isempty(head))
cout<<"List is empty."<<endl;
else if (head == last)
{
delete head;
head == NULL;
last == NULL;
}
else
{
node *temp = head;
head = head->next;
delete temp;
}
}
void removelast(node *&head, node *&last)
{
if(isempty(head))
cout<<"List is empty."<<endl;
else if (head == last)
{
delete last;
head == NULL;
last == NULL;
}
else
{
node *temp = last;
last = last->next;
delete temp;
}
}
void shownode(node *current)
{
if (isempty(current))
cout<<"list is empty"<<endl;
else
{
cout<<"Nodes in list:"<<endl;
while(current != NULL)
{
cout<<current->number<<endl;
current = current->next;
}
}
}
void showreverse(*&last)
{
}
int main()
{
node *head = NULL;
node *last = NULL;
char choice;
int number;
do{
choice = menu();
switch(choice)
{
case '1': cout<<"inert number:"<<endl;
cin>>number;
insert(head, last, number);
break;
case '2': addlast(head, last, number);
break;
case '3': removefirst(head, last);
break;
case '4': removelast(head, last);
break;
case '5': shownode(head);
break;
case '6': showreverse(last);
break;
default: cout<<"Exit";
}
}while(choice != '4');
return 0;
}
In your removelast(node *&head, node *&last) function when you delete the last element, the next member of the last but one node will still point to the last element you deleted.
node *temp = last;
last = last->next;
delete temp;
You are making a pointer to the same node, change its next member and than delete it, so the first two instructions are useless. The problem is at the last but one next member, but you have not way of changing it without iterating over the whole list. I think the best approach is to use a doubly linked list. With doubly linked list just interchange last pointer with head pointer, or parse it from last to head.