Segmentation fault in queue program when using push - c++

Im getting a segmentation fault when i try to push elements into the queue, im not an expert working with queues so i dont recognize where the problem is.
I have been searching for the solution to this problem and even though people get similar problems i didnt help me fix my problem.
Here is the code:
(I used the debug option in Dev-c ++ 5.9.2 and it told me the line "temp->link = NULL;" is causing the problem but i have no idea how to fix it)
#include <iostream>
using namespace std;
struct Node {
int data;
Node* link;
};
class Queue {
public:
Queue();
~Queue();
void pushBack(int d);
bool popFront();
bool isEmpty();
void displayQueue();
private:
Node* back;
Node* front;
};
Queue::Queue() {
back = NULL;
front = NULL;
}
Queue::~Queue() {
while (!isEmpty()) {
popFront();
}
}
void Queue::pushBack(int d) {
Node* temp;
if (temp == NULL) {
return;
} else {
temp->link = NULL; <========== This is where is get the error
if (back == NULL) {
back = temp;
front = temp;
} else {
front->link = temp; <===== here too
front = temp;
}
}
}
bool Queue::popFront() {
if (front == NULL) {
return false;
} else {
Node* removeNode;
removeNode = front;
if (back == front) {
back = NULL;
front = NULL;
} else {
Node* previousFront = back;
while (previousFront->link != front) {
previousFront = previousFront->link;
}
front = previousFront;
front->link = NULL;
}
delete removeNode;
return true;
}
}
bool Queue::isEmpty() {
return (back == NULL);
}
void Queue::displayQueue() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
Node *current;
current = back;
cout << endl << "-- BACK -- ";
while (current != NULL) {
cout << current->data << " ";
current = current->link;
}
cout << "-- FRONT --" << endl << endl;
}
}
int main(){
Queue q;
q.displayQueue();
q.pushBack(20);
q.pushBack(30);
q.displayQueue();
q.pushBack(40);
q.pushBack(12);
q.displayQueue();
q.popFront();
q.displayQueue();
return 0;
}

You have to know that when you add a new
node to the list you constructed, you need to allocate a dynamic
location for the new node and then add it to the list -queue-;
second thing : when the back is pointing already at some node in the link
you need to make the new node points at the node the back was pointing at,
then make the back pointer points at the new node .
the new function (pushBack) bacomes :
void Queue::pushBack ( int d ) {
Node* temp = new Node;
temp->data = d;
temp->link = NULL;
if (back == NULL) {
back = temp;
front = temp;
}
else {
temp->link = back;
back = temp;
}
}

You are creating a pointer to a node, but you have not created the node yet. (what everyone else has said)
change
Node* temp; - stack memory
To
Node *temp = new Node() - heap memory

im not an expert working with queues so i dont recognize where the problem is
Note that the problem has nothing to do with queues: The problem is understanding how the language works.
As Thornkey pointed out, you have a temp var in your pushBack function. It's a pointer, but it points to random data until you tell what to point at. When you follow the pointer, it could go anywhere and get a segfault or break some other part of your program.

Related

I made my own custom stack and want to know how is there a way to iterate through the stack in reverse

This is the interface file
#ifndef STACK_H
#define STACH_H
#include<iostream>
using namespace std;
class Stack
{
struct StackFrame{
char data;
StackFrame* next;
};
StackFrame* head;
public:
Stack();
void push(char);
char pop();
void empty();
bool check_empty();
void print();
//Note:This code prints the data in stack format !!!
~Stack();
};
#endif // !STACK_H
This is the implementation file
#include "Stack.h"
Stack::Stack():head(nullptr){}
void Stack::push(char c)
{
StackFrame* temp = new StackFrame;
temp->data = c;
temp->next = nullptr;
if (head == nullptr)
{
head = temp;
return;
}
temp->next = head;
head = temp;
}
char Stack::pop()
{
if (head == nullptr)
{
cerr << "There is nothing in the stack to pop at the moment!!!" << endl;
return '\0';
}
StackFrame* holder = head;
char temp_chr = holder->data;
head = head->next;
free(holder);
holder = nullptr;
return temp_chr;
}
void Stack::empty()
{
StackFrame* holder;
while(head!=nullptr)
{
holder = head;
head = head->next;
free(holder);
}
holder = nullptr;
head = nullptr;
}
bool Stack::check_empty()
{
return head==nullptr;
}
void Stack::print() {
if (head == nullptr)
{
cerr << "Nothing in stack at the moment :( " << endl;
return;
}
StackFrame* holder = head;
while (holder != nullptr)
{
cout << holder->data;
holder = holder->next;
}
cout << endl;
}
Stack::~Stack()
{
empty();
}
This is the application file
#include"Stack.h"
#include<string>
int main()
{
int num;
string push;
Stack st;
cout << "Enter your name = ";
getline(cin, push);
for (int i = 0; i < push.length(); i++)
{
st.push(push[i]);
}
st.print();
cout << "How many times do you want to pop? = ";
cin >> num;
for (int i = 0; i < num; i++)
{
st.pop();
}
st.print();
return EXIT_SUCCESS;
}
Can someone help me out on how to reverse iterate in this stack class which i made myself using the concept of linked list, i googled a bit and got the gist of things to use tail , Can someone elaborate another way if possible please or share a link to a site. It will help me out later a lot when i start working on binary trees and if i ever need to reverse iterate in the binary tree nodes.
First of all as mentioned above, stack is LIFO data structure and thus should use another data structure for that purpose.
Second, you can use second stack and copy data over to new stack, which is expensive.
Third option would be to go from the top and kip a track and store pointer to the previous node and to the pointer that point to the previous of previous node. Something like this:
struct reverseStack {
StackFrame* node;
reverseStack* previousPointer;
reverseStack (StackFrame* n, ReverseStack* p) :
node (n), previousPointer(p) { }
}
than using simple for loop you create pointer to the top, and go to the next and store that info into this structure. In your code you have something like this:
reverseStack top (nullptr, topFrame);
StackFrame currentFrame = top->next();
ReverseStack current; = top;
while (currentFrame != nullptr) {
// alghoritm for linking previous nodes.
}
I think you should add a second Stack object rather than a second list.
Recursive algorithm would have worked fine (use the recursive call stack as your "reverse" stack).
void Stack::print(StackFrame *pCurr) {
if (pCurr != nullptr)
{
print(pCurr->Next);
cout << pCurr->ch;
}
}
void Stack::print() {
if (head == nullptr)
{
cerr << "Nothing in stack at the moment :( " << endl;
return;
}
print(head);
cout << endl;
}

I am getting a breakpoint and i do not know why

I am trying to implement a priority Queue by using a linked list in c++. However, when I run the program it triggers a breakpoint within "priorityQLinkedList::dequeue()" method. Can someone tell why this is the case and give me suggestions on how to fix it?
Code:
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
struct DAT
{
int id;
char fullname[50];
double savings;
};
struct NODE
{
DAT data;
NODE *N;
NODE *P;
NODE(const int i, const char *f, const double s)
{
data.id = i;
strcpy_s(data.fullname, f);
data.savings = s;
N = NULL;
P = NULL;
}
};
class priorityQLinkedList
{
private:
NODE *front;
NODE *back;
public:
priorityQLinkedList() { front = NULL; back = NULL; }
~priorityQLinkedList() { destroyList(); }
void enqueue(NODE *);
NODE* dequeue();
void destroyList();
};
void priorityQLinkedList::enqueue(NODE *n)
{
if (front == NULL) {
front = n;
back = n;
}
else {
NODE *temp = front;
if (n->data.id > temp->data.id)
{
front->P = n;
n->N = front;
front = n;
}
else
{
//search for the posistion for the new node.
while (n->data.id < temp->data.id)
{
if (temp->N == NULL) {
break;
}
temp = temp->N;
}
//New node id's smallest then all others
if (temp->N == NULL && n->data.id < temp->data.id)
{
back->N = n;
n->P = back;
back = n;
}
//New node id's is in the medium range.
else {
temp->P->N = n;
n->P = temp->P;
n->N = temp;
temp->P = n;
}
}
}
}
NODE* priorityQLinkedList::dequeue()
{
NODE *temp;
//no nodes
if (back == NULL) {
return NULL;
}
//there is only one node
else if (back->P == NULL) {
NODE *temp2 = back;
temp = temp2;
front = NULL;
back = NULL;
delete temp2;
return temp;
}
//there are more than one node
else {
NODE *temp2 = back;
temp = temp2;
back = back->P;
back->N = NULL;
delete temp2;
return temp;
}
}
void priorityQLinkedList::destroyList()
{
while (front != NULL) {
NODE *temp = front;
front = front->N;
delete temp;
}
}
void disp(NODE *m) {
if (m == NULL) {
cout << "\nQueue is Empty!!!" << endl;
}
else {
cout << "\nID No. : " << m->data.id;
cout << "\nFull Name : " << m->data.fullname;
cout << "\nSalary : " << setprecision(15) << m->data.savings << endl;
}
}
int main() {
priorityQLinkedList *Queue = new priorityQLinkedList();
NODE No1(101, "Qasim Imtiaz", 567000.0000);
NODE No2(102, "Hamad Ahmed", 360200.0000);
NODE No3(103, "Fahad Ahmed", 726000.0000);
NODE No4(104, "Usmaan Arif", 689000.0000);
Queue->enqueue(&No4);
Queue->enqueue(&No3);
Queue->enqueue(&No1);
Queue->enqueue(&No2);
disp(Queue->dequeue());
disp(Queue->dequeue());
disp(Queue->dequeue());
disp(Queue->dequeue());
disp(Queue->dequeue());
delete Queue;
return 0;
}
One problem which stands out in your dequeue() method is that you are calling delete on a NODE pointer, and then attempting to return this deleted pointer to the caller. This could cause an error either in dequeue() itself, or certainly in the caller who thinks he is getting back a pointer to an actual live NODE object.
One potential fix would be to create a copy of the NODE being dequeued. You would still remove the target from your list, but the caller would then be returned a valid pointer, which he could free later.
NODE* priorityQLinkedList::dequeue()
{
NODE *temp;
// no nodes
if (back == NULL) {
return NULL;
}
NODE *temp2 = back;
temp = new NODE(temp2->data.id, temp2->data.fullname, temp2->data.savings);
// there is only one node
else if (back->P == NULL) {
front = NULL;
back = NULL;
delete temp2;
return temp;
}
// there are more than one node
else {
back = back->P;
back->N = NULL;
delete temp2;
return temp;
}
}
You're deleting pointers in dequeue that priorityQLinkedList does not own, so you don't know if it is safe to delete them.
In this case, they are not since the node pointers passed to enqueue are addresses of local, stacked based variables and have not been allocated by new. (There's also the already mentioned problem of deleting a pointer then returning it, which is Undefined Behavior.)
The fix for the code as shown is to remove the calls to delete in dequeue. However, if changes are made so that the nodes passed to enqueue are dynamically allocated, you'll need to add something to handle that.
1.First change strcpy_s to strcpy is struct NODE.
2.Instead of Delete(temp2) use temp2--.
//no nodes
if (back == NULL) {
return NULL;
}
//there is only one node
else if (back->P == NULL) {
NODE *temp2 = back;
temp = temp2;
front = NULL;
back = NULL;
temp2--;
return temp;
}
//there are more than one node
else {
NODE *temp2 = back;
temp = temp2;
back = back->P;
back->N = NULL;
temp2--;
return temp;
}
I hope this will resolve the problem.

Implementing a Queue Class, Segmentation Fault?

I'm attempting to implement a Queue Class (using a Node struct, and Queue class).
I'm getting a segmentation fault and my eyes are failing me, I can't seem to find it.
My pushBack won't work and I'm pretty sure my popFront probably doesn't work. I'm just hoping somebody is able to give me a good push in the right direction!
Also, if you haven't been able to figure it out yet. I'm clearly very new to C++.
#include <iostream>
using namespace std;
struct Node {
int data;
Node* link;
};
class Queue {
public:
Queue();
~Queue();
void pushBack(int d);
bool popFront();
bool isEmpty();
void displayQueue();
private:
Node* back;
Node* front;
};
Queue::Queue() {
back = NULL;
front = NULL;
}
Queue::~Queue() {
while (!isEmpty()) {
popFront();
}
}
void Queue::pushBack(int d) {
Node* temp;
if (temp == NULL) {
return;
} else {
temp->link = NULL;
if (back == NULL) {
back = temp;
front = temp;
} else {
front->link = temp;
front = temp;
}
}
}
bool Queue::popFront() {
if (front == NULL) {
return false;
} else {
Node* removeNode;
removeNode = front;
if (back == front) {
back = NULL;
front = NULL;
} else {
Node* previousFront = back;
while (previousFront->link != front) {
previousFront = previousFront->link;
}
front = previousFront;
front->link = NULL;
}
delete removeNode;
return true;
}
}
bool Queue::isEmpty() {
return (back == NULL);
}
void Queue::displayQueue() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
Node *current;
current = back;
cout << endl << "-- BACK -- ";
while (current != NULL) {
cout << current->data << " ";
current = current->link;
}
cout << "-- FRONT --" << endl << endl;
}
}
int main(){
Queue q;
q.displayQueue();
q.pushBack(20);
q.pushBack(30);
q.displayQueue();
q.pushBack(40);
q.pushBack(12);
q.displayQueue();
q.popFront();
q.displayQueue();
return 0;
}
There is at least one major issue, in pushBack you are using temp without initializing it:
void Queue::pushBack(int d)
{
Node* temp;
if (temp == NULL) {
^^^^
Compiling with warnings turned on would have helped you here, using the -Wall flag with gcc would have given you the following warning:
warning: 'temp' is used uninitialized in this function [-Wuninitialized]
if (temp == NULL) {
^
Using a variable an unintialized automatic variable like this is undeined behavior which means the behavior of your program is unpredictable. Also see Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++1y? for reference.
What you probably meant to do was something like this:
Node* temp = new Node();
temp->data = d ;
Although setting up a constructor for Node would be better.
you cannot set a variable like this: temp->link = NULL;

findNode in binary search tree

Does this look right? I mean I am trying to implement the delete function.
Node* BST::findNode(int tofind) {
Node* node = new Node;
node = root;
while (node != NULL) {
if (node->val == tofind) {
return node;
} else if (tofind < node->val) {
node = node->left;
} else {
node = node->right;
}
}
}
Here is the delete, it's not even close to done but,
void BST::Delete(int todelete) {
// bool found = false;
Node* toDelete = new Node();
toDelete=findNode(todelete);
if(toDelete->val!=NULL) {
cout << toDelete->val << endl;
}
}
This causes a segmentation fault just running that, any ideas?
The main problem with findNode() is that you never return the node that you've found. That's why you're getting the segfault.
Also, in deleteNode() you should check whether findNode() has returned NULL. And of course you also need to code up the rest of the deletion logic.
Finally, the two new Node allocations are unnecessary and are leaking memory.
oh wait it's because in delete I should have done:
if(toDelete!=NULL) {
cout << toDelete->val << endl;
}
before it was
if(toDelete->val!=NULL)

LinkedList/Stack/Queue - Help with Dequeuing

I had to write a linked list, then turn it into a dynamic Stack, then turn that into a dynamic Queue. Well everything seems to work except the "dequeuing", right as the programs about to finish, it gives me an error: "An unhandled win32 exception occured in LinkedList_Stack_BNS11.exe [4972].".
I'm only assuming it's the dequeuing, because as I step through and/or run the program, it runs smoothly up till that part, so maybe I sent one of the pointers wrong or something?
Output:
Enquing 5 items....
// Finsihes
The values in the queue were (Dequeuing):
0
1
2
// Correct number in que but...
//Program gives that error right here. When it should finish and close.
If I included too much code let me know and I'll chop it down to just the "Dequeuing" (Which is in the very middle of all the stuff below)
Thanks in advance for the help!! I'm just not seeing what I did wrong. Thinking it maybe has something to do with where "head" is pointing? Idk.
Header File:
class NumberList
{
private:
//
struct ListNode
{
int value; // Value in this node
struct ListNode *next; // Pointer to the next node
};
ListNode *head; // List head pointer
ListNode *rear;
public:
//Constructor
NumberList()
{ head = NULL; rear = NULL; }
//Destructor
~NumberList();
//Stack operations
bool isEmpty();
//Queue operations
void enqueue(int);
void dequeue(int &);
};
#endif
List_Stack_Queue.cpp:
bool NumberList::isEmpty()
{
bool status;
if(!head)
status = true;
else
status = false;
return status;
}
void NumberList::enqueue(int num)
{
ListNode *newNode; // Point to a new node
// Allocate a new node and store num there.
newNode = new ListNode;
newNode->value = num;
//If there are no nodes in the list
// make newNode the first node.
if(isEmpty())
{
head = newNode;
rear = head;
//newNode->next = NULL;
}
else
{
rear->next = newNode;
rear = rear->next;
//newNode->next = head;
//head = newNode;
}
}
void NumberList::dequeue(int &num)
{
ListNode *temp;
if(isEmpty())
cout << "The queue is empty.\n";
else
{
num = head->value;
temp = head;
head = head->next;
delete temp;
}
}
MAIN:
const int MAX_VALUES = 3;
// Create a DynIntQueue object.
NumberList iQueue;
// Enqueue a series of numbers.
cout << "Enqueuing " << MAX_VALUES << " items...\n";
for (int x = 0; x < MAX_VALUES; x++)
iQueue.enqueue(x);
cout << endl;
//Dequeue and retrieve all numbers in the queue
cout << "The values in the queue were (Dequeuing):\n";
while(!iQueue.isEmpty())
{
int value;
iQueue.dequeue(value);
cout << value << endl;
}
return 0;
Last nodes's next element should be set to NULL in a linked list. So,
void NumberList::enqueue(int num)
{
// ...
if(isEmpty())
{
head = newNode;
head->next = NULL;
rear = head;
}
else
{
rear->next = newNode;
rear = rear->next;
rear->next = NULL; // Pointing the next node element to null.
}
}
To, me it seems some thing is wrong with Numberlist::isEmpty(); member function. How you are deciding whether the list is empty or not ? Show the definition of it.