Visual studio 2017 code not outputting after a certain line - c++

I am writing a program that takes 8 user inputted integers and makes a linked list out of them. I have the program print the linked list, then I delete the last node and print the list in reverse. Along the way I've been testing to program to make sure each part works, and it's worked up to the point of printing out the original linked list.
When I finished writing the code for the modification and then printing part, I ran into a problem - the program won't output anything after printing out the original list. So for example, if I input 1,2,3,4,5,6,7,8, it will output:
1
2
3
4
5
6
7
8
and that's it. I've tried putting cout << "testing"; at different points to see where my code stops outputting and the latest point where it successfully outputs is right before the while loop.
I'm not sure why a while loop would cause the program to straight up stop outputting anything, even an arbitrary cout statement that has nothing to do with the while loop itself, so I figured I'd ask on here. I'm using visual studio 2017 if that helps. Thanks for any and all help!
#include <iostream>
using namespace std;
void getdata(int & info); //function that assigns a user inputted value to each node
const int nil = 0;
class node_type // declaration of class
{
public:
int info;
node_type *next;
};
int main()
{
node_type *first, *p, *q, *r, *newnode;
first = new node_type;
newnode = new node_type;
int info;
getdata(info); //first node
(*first).info = info;
(*first).next = nil;
getdata(info); //second node
(*newnode).info = info;
(*first).next = newnode;
(*newnode).next = nil;
p = newnode;
for (int i = 2; i < 8; i++) //nodes 3-8
{
newnode = new node_type;
getdata(info);
(*newnode).info = info;
(*p).next = newnode;
p = newnode;
(*newnode).next = nil;
}
q = first;
while (q != nil) // printing linked list
{
cout << (*q).info << "\n";
q = (*q).next;
}
//deletes last node then reverses list
p = first;
q = (*p).next;
r = (*q).next;
if (first == nil) //if list is empty
cout << "Empty list";
else if ((*first).next == nil) //if list has one node
first = nil;
else if (r == nil) //if list has two nodes
q = nil;
else //general case
{
(*first).next = nil; //last line where when i put a cout << ""; it prints in the output window
while ((*r).next != nil)
{
(*q).next = p;
(*r).next = q;
p = q;
q = r;
r = (*r).next;
}
(*q).next = p;
first = q;
}
q = first;
while (q != nil) // printing newly modified list.
{
cout << (*q).info << "\n";
q = (*q).next;
}
return 0;
}
void getdata(int & info)
{
cout << "Enter number: \n";
cin >> info;
}

else //general case
{
(*first).next = nil; //last line where when i put a cout << ""; it prints in the output window
while ((*r).next != nil)
{
(*q).next = p;
(*r).next = q;
p = q;
q = r;
r = (*r).next;
}
(*q).next = p;
first = q;
}
You run into an infinite loop when reversing your list. That's why it doesn't output anything.
As soon as you link element 2 to element 3, you link element 3 to element 2 in the next step.
That causes an infinite loop when iterating through the list while reversing it.
A proper way to reverse it in the general case would be like that:
else //general case
{
node_type* current = first;
node_type* next = first->next;
(*first).next = nil; //last line where when i put a cout << ""; it prints in the output window
while (next)
{
node_type* temp = next->next;
next->next = current;
current = next;
next = temp;
}
first = current;
}
On a sidenote, you should use bla->foo to dereference, instead of (*bla).foo.

Related

Why do I receive a "signal SIGSEGV, segmentation fault" when I try to delete last elements from doubly linked list?

This is a programming assignment from university. The main program was given to me by the professor. I have to create the dlist.h. When I debug, I receive this segmentation error. I also have this:
get (dl=..., val=<error reading variable>) at dlist.h:37
#include <iostream>
#include <exception>
struct DListElem { //element of the list
int info;
DListElem * prev;
DListElem * next;
};
struct DList{ //just stores pointers to first and last elements of the list
DListElem * first;
DListElem * last;
};
void initializeDList(DList & dl){ //Iinitializes dl as empty list
dl.first = nullptr;
dl.last = nullptr;
}
void put(DList& dl, int val){ //insert a new element with value val at the beginning of the list.
DListElem* front_elem = new DListElem;
front_elem ->info = val;
front_elem -> prev = nullptr;
front_elem -> next = dl.first;
dl.first = front_elem;
if(dl.last==NULL) dl.last=dl.first;
}
bool get(DList& dl, int& val){
/*Removes an item (if possible) from the end of the list. The value of the last
element is returned by the val parameter, the memory for the list element
is released. The return value indicates whether an item could be retrieved,
i.e. it returns false for an empty list and true otherwise.*/
if(dl.last==nullptr) return false;
if (dl.first==dl.last){ //if there is only 1 element
val = dl.last -> info;
DListElem* buffer = new DListElem;
buffer = dl.last;
dl.last = nullptr;
dl.first = nullptr;
delete (buffer);
}
else{
val = dl.last -> info;
DListElem* buffer = new DListElem;
buffer = dl.last;
dl.last = dl.last -> prev;
dl.last -> next = nullptr; //this part seems to still be the problem
delete (buffer);
};
return true;
}
And this is my main program:
#include <iostream>
#include "dlist.h"
using namespace std;
int main (int argc, char *argv[]) {
DList queue;
initializeDList (queue);
inserts 5 values
for (int i = 1; i <= 5; i++) {
cout << "put: " << 10 * i << endl;
put (queue, 10 * i);
}
removes 3 values and prints them to console
for (int j = 1; j <= 3; j++){
int value;
if (get (queue, value))
cout << " get: " << value << endl;
}
I guess these are necessary:
cin.sync ();
cin.get ();
return 0;
}
okay, the issue was with the function put(); I didn't implement it well enough and it produced only a single linked list; consequently, dl.last became null in the function get() and the expression dl.last -> next = nullptr; was the reason for the problem;
this is the corrected put()
put (DList & dl, int val)
{ //insert a new element with value val at the beginning of the list.
DListElem *front_elem = new DListElem;
front_elem->info = val;
front_elem->prev = nullptr;
front_elem->next = dl.first;
if (dl.first != nullptr && dl.first->next == nullptr)
dl.last = dl.first;
if (dl.first != nullptr)
dl.first->prev = front_elem;
dl.first = front_elem;
}

Doubly linked list not taking input after calling a delete function

Greetings stack overflow. My program is supposed to take a user inputted line of characters and append them to a list. The program is also supposed to delete the most recent character appended if a hashtag is read in the input.
My program mostly works, but I run into errors when I try to break it by adding too many hashtags. Upon doing this the list stops accepting appends will display nothing if one too many hashtags are used.
I hope I only included what I thought was useful code, sorry if the main function was not necessary.
#include <iostream>
using namespace std;
class doubleList
{
public:
doubleList() { first = NULL; } // constructor
void append(char); // adds entry to the end of the list
void remove_last(); // removes the last item from a list
friend ostream& operator<<(ostream& out, const doubleList& l); // outputs in forward order
private:
struct Node
{
char data;
Node *next;
Node *prev;
};
Node *first;
Node *last;
};
void doubleList::append(char entry)
{
Node* temp = new Node();
temp -> data = entry;
temp -> next = NULL;
if (first == NULL)
{
first = temp;
last = temp;
}
else
{
last -> next = temp;
temp -> prev = last;
last = temp;
}
}
void doubleList::remove_last()
{
if (first -> next == NULL)
{
delete first;
}
else if (first != NULL)
{
last = last -> prev;
delete last -> next;
last -> next = NULL;
}
}
ostream& operator<<(ostream& out, const doubleList& l)
{
doubleList::Node* q;
q = l.first;
while (q != NULL)
{
out << q -> data;
q = q -> next;
}
return out;
}
int main()
{
doubleList list;
char ch[100];
cout << "Enter a line of characters; # will delete the most recent character." << endl;
for (int i = 0; i < 100; i++)
{
cin.get(ch[i]);
list.append(ch[i]);
if (ch[i] == '#')
{
list.remove_last();
list.remove_last(); // called twice becaue it removes the hashtag from the list
} // and i was too lazy to make it so it doesnt do that so this
// is simply an easier fix
if (ch[i] == '\n') // exits the loop when enter is clicked
break;
}
cout << list;
return 0;
}
A successful run of my program would look like:
Enter a line of characters; # will delete the most recent character.
abcd##fg
abfg
My program when too many hashtags are added:
Enter a line of characters; # will delete the most recent character.
ab#####efgh
Nothing is shown after user input is taken. Thanks in advance.
You should also set the pointer last to nullptr in the constructor
doubleList() { first = nullptr; last = nullptr; }
The function append is incorrect because it does not set the data member prev of the first node appended to the list. It should be written like
void doubleList::append(char entry)
{
Node* temp = new Node();
temp -> data = entry;
temp -> next = nullptr;
temp -> prev = last;
if (first == NULL)
{
first = temp;
}
else
{
last -> next = temp;
}
last = temp;
}
The function removeList can invoke undefined behavior because in the very beginning of the function it does not check whether the pointer first is equal to nullptr. And after deleting the node pointed to by the pointer first it does not set the pointers first and last to nullptr. The function can be defined the following way.
void doubleList::remove_last()
{
if ( last )
{
Node *tmp = last;
last = last->prev;
if ( last != nullptr )
{
last->next = nullptr;
}
else
{
first = nullptr;
}
delete temp;
}
}
You rely on first being NULL when deallocated in remove_last() but do not set it after the free. As your code is incomplete, I cannot tell what last is, and why you your logic doesn't rely on it in remove_last() instead of first.
Something along these lines (untested);
void doubleList::remove_last() {
if(!last) return;
if(last == first) {
free last;
first = nullptr;
last = nullptr;
return;
}
last = last->prev;
free last->next;
last->next = nullptr;
}

Code in involving round robin scheduling fails to run or gives a segmentation fault(core dumped)

(C++) My code is supposed to mimic the round robin cpu scheduling algorithm using linked lists (so accept list of process names with times ex: ProcessA 10, subtract 3 from the times, if the result is greater than 0 it is shifted to end of list. This continues until process time reaches 0 where at that point the process is finished).
My program accepts and displays the list of processes and their times correctly. So I didn't include the code for accepting, creating, and displaying the list. Somewhere after displaying the list the user has inputted, the program just abruptly ends for some reason.
my output:
[John#fish lab2]$ ./a.out
Enter your processes, to end press '^d'
ProcessA 4
Enter your processes, to end press '^d'
ProcessB 10
Enter your processes, to end press '^d'
ProcessC 6
Enter your processes, to end press '^d'
^d
Displaying the list of processes:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ProcessA 4
ProcessB 10
ProcessC 6
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I tried modifying the while loop since I thought there was an issue with the flag so I changed it from while(print_flag) to while(true) and placed a break statement in the else condition.
my output:
same as last ouput except with an extra line saying : 'segmentation fault(core dumped)'
I have no idea on how to fix the underlying issue. Any help is appreciated.
#include <iostream>
#include <list>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string>
using namespace std;
volatile sig_atomic_t print_flag = false;
struct NodeType
{
string value1; //process name
int value2; //process time
NodeType* next;
void DisplayLinkedList(NodeType* head)
{
NodeType* p;
p = head; //initialize pointer p to point to the first node in the linked list
cout << "Displaying the list of processes: " << endl;
cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
while (p != NULL)
{
cout << p->value1 << " " << p->value2 << endl;
p = p->next; //update p to point to next node in the linked list ...
}
cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
cout << " " << endl;
}
void createnode(NodeType*& head, string x, int y)
{
NodeType* p = new NodeType;
if (head == NULL)
{
p->value1 = x;
p->value2 = y;
p->next = NULL;
head = p;
}
else
{
p = head;
while (p->next != NULL)
p = p->next;
p->next = new NodeType;
p = p->next;
p->value1 = x;
p->value2 = y;
p->next = NULL;
}
}
bool IsEmpty(NodeType* h) const
{
return h == NULL;
}
void DeleteNode(NodeType*& head)
{
NodeType* p = head;
head = head->next;
delete p;
}
void roundrobin(NodeType*& head)
{
head->value2 -= 3;
if (head->value2 == 0) // no time remaining
{
cout << head->value1 << " Finished" << endl;
DeleteNode(head);
}
else // time remaining
{
NodeType* p = head;
p->next = NULL;
head = head->next;
NodeType* q = head;
while (q->next != NULL)
q = q->next;
q->next = p;
}
}
};
void handle_alarm(int sig) // interrupt handler, manipulates flags to allow roundrobin to run
{
print_flag = true;
}
int main()
{
NodeType* head = NULL;
NodeType a;
string v, x, y;
int argc = 0;
int z = 0;
while(true)
{
cout << "Enter your processes, to end press '^d' " << endl;
getline(cin, v);
if (v == "^d")
break;
//cin >> a;
int index = v.find(" ");
x = v.substr(0, index);
y = v.substr(index + 1, v.length());
z = stoi(y);
a.createnode(head, x, z);
argc++;
}
a.DisplayLinkedList(head);
signal(SIGALRM, handle_alarm);
alarm(3);
while (print_flag)
{
if (a.IsEmpty(head) == false) // list not empty
{
a.roundrobin(head);
a.DisplayLinkedList(head);
}
else
{
cout << "No more processes left" << endl;
print_flag = false;
}
//print_flag = false;
alarm(3);
}
return 0;
}
I think you need to make some small changes in your roundrobin function for it to work:
You need to update the condition to check if a process is finished to
head->value2 <= 0 instead of head->value2 == 0 since head->value2 == 0 seems only to work for any process with value2 is divisible by 3 and it will miss other processes as they will be minus down to negative numbers through this expression head->value2 -= 3
You also need to bring your p->next = NULL; line after head = head->next; instead of before. Otherwise, head will always be NULL as p is currently head.
Finally, you need to check for if head is the only process left (head->next != NULL) before switching to the next process. Otherwise, you would make your head becomes NULL if head->next is NULL, causing segmentation fault error
void roundrobin(NodeType*& head)
{
head->value2 -= 3;
if (head->value2 <= 0) // no time remaining
{
cout << head->value1 << " Finished" << endl;
DeleteNode(head);
}
else // time remaining
{
NodeType* p = head;
if (head->next != NULL) {
head = head->next;
p->next = NULL;
NodeType* q = head;
while (q->next != NULL)
q = q->next;
q->next = p;
}
}
}

Pointers in Linked List [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm new to C++, so my code is not optimal, but at the moment I just want it to work.
I have to write a function that compares every 2 elements (1. and 2., 2. and 3. etc.) of linked list and deletes the first of these two elements if it's smaller than the next one. At the end I have to display the list adter editing. I found some examples of what I'm trying to do, but they make me confused and I have no idea how to adjust them to my case.
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
struct elements {
int value;
elements * next;
};
void f (elements * & start){
if (start == NULL || start -> next == NULL) {
return;
}
elements * p = start, * prevvalue = NULL, * previous = NULL, * del, * before = NULL, * after = NULL;
int first = start -> value;
int second = 0;
for (; p != NULL; p = p -> next){
cout << p -> value << endl;
second = p -> value;
if (first < (p -> value)) {
before = prevvalue;
del = p;
previous = p;
p -> next = after -> next;
after -> next = p;
delete del;
}
first = second;
previous = prevvalue;
}
if (previous == NULL) start = start -> next;
else prevvalue -> next = start -> next;
}
int main (){
elements * start = NULL, * last = NULL, * input;
int count;
cout << "How many elmenets would you like to input? ";
cin >> count;
for (int i = 0; i < count; i++){
cout << "Please input " << i + 1 << ". element: ";
elements * input = new elements;
cin >> input -> value;
input -> next = NULL;
if (last != NULL) {
last -> next = input;
last = input;
}
else start = last = input;
}
f (start);
elements * p = start;
while (p != NULL) {
cout << p -> value << endl;
p = p -> next;
}
input = start;
while (start != NULL){
elements * temp = start;
start = start -> next;
delete temp;
}
return 0;
}
There's something totally wrong with pointers, so it's not working.
Can someone please edit my code and throw out everything that's unnecessary?
Thank you in advance!
After some cleanup something like this
#include <iostream>
#include <cstdlib>
using namespace std;
struct elements {
int value;
elements* next;
};
elements* funkcija(elements *start) {
if (start == NULL || start->next == NULL) {
return start;
}
elements *list = start;
elements *current = start;
elements *previous = nullptr;
while(current) {
elements* next = current->next;
if (!next) {
break;
}
if (current->value < next->value) {
if (previous) {
delete current;
previous->next = next;
}
else {
list = next;
delete current;
}
current = nullptr;
}
else {
previous = current;
}
current = next;
}
return list;
}
int main() {
elements *start = NULL, *last = NULL;
int count;
cout << "How many elmenets would you like to input? ";
cin >> count;
for (int i = 0; i < count; i++) {
cout << "Please input " << i + 1 << ". element: ";
elements* input = new elements;
cin >> input->value;
input->next = NULL;
if (last != NULL) {
last->next = input;
last = input;
}
else {
start = last = input;
}
}
start = funkcija(start);
elements * p = start;
while (p != NULL) {
cout << p->value << endl;
p = p->next;
}
while (start != NULL) {
elements * temp = start;
start = start->next;
delete temp;
}
return 0;
}

How to display all list values without endless loop

I have a list and I want to display it's values.
I want to see 1 2 3 4, but I have a endless loop like 1 2 3 4 1 2 3 4 1 2..
Can't understand, why?
struct node
{
int item;
node *next;
node(int x, node *t)
{
item = x;
next = t;
}
};
int main()
{
node *firstElement = new node(1, NULL);
firstElement->next = firstElement;
node *lastElement = firstElement;
for (int i = 2; i < 5; i++)
lastElement = (lastElement->next = new node(i, firstElement));
for (node *first = lastElement; first != 0; first = first->next)
cout << first->item << " ";
delete firstElement;
return 0;
}
Try using this code:
struct node
{
int item;
node *next;
node(int x, node *t)
{
item = x;
next = t;
}
};
int main()
{
node *firstElement = new node(1, NULL);
node *lastElement = firstElement;
for (int i = 2; i < 5; i++)
lastElement = (lastElement->next = new node(i, nullptr));
for (node *first = firstElement; first != 0; first = first->next)
cout << first->item << " ";
return 0;
}
IdeOne live code
The problem is that you set the "next" link of your last node to this node itself, not nullptr.
Also, it's better to delete the memory allocated
The problem is that your data structure has an infinite loop in itself: this line
firstElement->next = firstElement;
makes firstElement point back to itself, creating a circular list. When you add more elements, your list remains circular, so exit condition first == 0 is never achieved.
If you want your list to remain linear, not circular, your insertion code should be modified as follows:
node *firstElement = new node(1, NULL);
node *lastElement = firstElement;
for (int i = 2; i < 5; i++) {
lastElement->next = new node(i, lastElement->next)
lastElement = lastElement->next;
}
The printing code should start with firstElement:
for (node *current = firstElement; current != 0; current = current->next)
cout << current->item << " ";
Finally, deleting a single firstItem is not sufficient. You need a loop to traverse the whole list. Alternatively, you could chain deletion in the destructor by calling delete next, but this is dangerous, because recursive invocation of destructors may overflow the stack.
You have a loop in your list, because lastElement->next always points to firstElement. This is why first will never be equal to 0.
If you really need a loop I think you should write something like this:
node* p = firstElement;
do {
cout << p->item << " ";
p = p->next;
} while (p != firstElement);
The problem is that you create every node with firstElement as its next.
This would make sense if you were adding nodes to the front of the list, but you're adding them at the back, so the last node will point back to the start.
Since you're adding to the back, terminate the list on every insertion instead:
lastElement->next = new node(i, nullptr))