Sometimes the code runs till the end without any errors while other times it stops in the middle and gives me this error Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) here is a picture of it (https://i.stack.imgur.com/uZDX1.png). The error is in my header file named Functions, and the compiler used in this picture is Xcode on a Mac device. I also tried another compiler "Visual Studio" on a Windows device and the code never runs till the end, it always stops in the middle of running and gives me an error in the same line of code, here is a picture of the error Visual Studio gave me Error in Visual Studio.
#include <iostream>
using namespace std;
//products' data
struct products{
int ID;
string Name;
double Price;
int Quantity;
};
//receipt
struct receipt{
string name;
double price;
receipt* link;
};
struct linkedListFunctions{
//inserts node at the end of the list
void insert(receipt** head_name_ref, string new_name, double new_price)
{
receipt* new_name_node = new receipt();
receipt *last = *head_name_ref;
new_name_node->name = new_name;
new_name_node->price = new_price;
new_name_node->link = NULL;
if (*head_name_ref == NULL)
{
*head_name_ref = new_name_node;
return;
}
while (last->link != NULL)//The error is right here
{
last = last->link;
}
last->link = new_name_node;
return;
}
//prints list
void printReceipt(receipt* n){
while(n!=NULL){
cout<<n->name<<": ";
cout<<n->price<<'\t'<<" ";
cout<<endl;
n=n->link;
}
}
//removes first node in the list
receipt* removeFirstreceipt(struct receipt* head)
{
if (head == NULL)
return NULL;
receipt* temp = head;
head = head->link;
delete temp;
return head;
}
};
The first two code boxes are in the header file named Functions.h The error is in the second code box at line 15, it has a comment next to it
#include "Functions.h"
int main(){
struct products details[5];
details[0] = {0, "Apple Juice", 12, 240};
details[1] = {1,"Bread", 10, 100};
details[2] = {2, "Chocolate", 5, 500};
details[3] = {3, "Dates", 50, 150};
details[4] = {4, "Eggs", 30, 360};
linkedListFunctions list;
//declaring first node in receipt linked list
receipt* head = NULL;
head = new receipt;
//prints all products IDs and Names
for (int i=0; i<5; i ) {
cout<<details[i].ID<<": ";
cout<<details[i].Name<<" ";
cout<<details[i].Price<<"LE"<<endl;
}
char buyAgain;
while ((buyAgain='y' && buyAgain!='n')){
//choosing a product
cout<<"Enter the product's ID to choose it: ";
int chooseProduct;
cin>>chooseProduct;
cout<<"ID: "<<details[chooseProduct].ID<<endl
<<"Name: "<<details[chooseProduct].Name<<endl
<<"Price: "<<details[chooseProduct].Price<<endl
<<"Quantity: "<<details[chooseProduct].Quantity<<endl<<"********"<<endl;
//choosing the quantity
cout<<"How much "<<details[chooseProduct].Name<<" do you want? ";
int chooseQuantity;
cin>>chooseQuantity;
list.insert(&head, details[chooseProduct].Name, details[chooseProduct].Price*chooseQuantity);//
details[chooseProduct].Quantity=details[chooseProduct].Quantity-chooseQuantity;
cout<<details[chooseProduct].Name<<" Left: "<<details[chooseProduct].Quantity<<endl<<"********"<<endl;
cout<<"Would you like to order something else? y=yes n=no";
cin>> buyAgain;
switch(buyAgain) {
case 'y':
break;
case 'n':
//prints receipt
cout<<"***Receipt***"<<endl;
list.printReceipt(head);
}
}
}
The last code box is the main function
CodePudding user response:
this is for sure wrong
char buyAgain;
while ((buyAgain = 'y' && buyAgain != 'n'))
you are attempting to test an uninitialized variable but are in fact assigning to it
2>C:\work\ConsoleApplication1\ConsoleApplication1.cpp(106): warning C4706: assignment within conditional expression
2>C:\work\ConsoleApplication1\ConsoleApplication1.cpp(106): warning C4701: potentially uninitialized local variable 'buyAgain' used
more importantly you do not initialize the fields on receipt, you should have a constructor for it, like this
struct receipt {
string name;
double price;
receipt* link;
receipt() { price = 0; link = nullptr; }
};
CodePudding user response:
For starters these lines
receipt* head = NULL;
head = new receipt;
do not make a great sense. The operator new creates an uninitialized object of the type receipt
(for example the data member link
can have an indeterminate value) that is a reason of undefined behavior when the pointer used in functions. What you need is just to write
receipt* head = NULL;
The condition in this while loop
while ((buyAgain='y' && buyAgain!='n')){
does not make a sense. buyAgain
is always set to 'y' in this sub-expression
buyAgain='y'
It seems you mean
while ( buyAgain == 'y' ){
or
while ( buyAgain != 'n' ){
But before the while loop you have to initialize the variable buyAgain
char buyAgain = 'y';
As the structure receipt is an affregate then instead of these statements within the function insert
receipt* new_name_node = new receipt();
new_name_node->name = new_name;
new_name_node->price = new_price;
new_name_node->link = NULL;
you could write
receipt* new_name_node = new receipt
{
new_name, new_price, nullptr
};
Pay attention to that the functions for processing the list declared in the structure struct linkedListFunctions
should be at least static member functions.
The parameter of the function printReceipt
should have teh qualifier const
void printReceipt( const receipt* n);
and teh output of blanks
cout<<n->price<<'\t'<<" ";
^^^^^^^^^^^^
in fact has no effect due to the next line
cout<<endl;