1

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

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Adel
  • 61
  • 5
  • Don't try to recover from that. If your program accesses out of bounds, Crom only knows what other damage has been done. The program is broken. Bail out as politely as you can and restart. For all you know the program's memory has been completely ed by a rogue pointer. Log it and get out. Then hunt and kill the bug. – user4581301 May 06 '22 at 20:55
  • You were advised to initialize your member variables in [this question you asked](https://stackoverflow.com/questions/72143067/this-problem-only-occurs-when-i-run-my-code-in-visual-studio-but-not-in-other-c). Did you do that? Also, stick to Visual Studio and fix it there, since that compiler always gives you the error. Your code invokes undefined behavior, and it is better to *always* reproduce the bug than to have it occur sometimes. – PaulMcKenzie May 06 '22 at 20:56
  • Another thing is that it becomes hard(er) to read your code due to all of the irrelevant things going on, such as menus and prompts. Your `main` function should consist of nothing except that `details` array, and direct calls to `insert`, `printReceipt`, etc. so that you exercise your list class *before* you start adding frills to it, such as menus. It's like painting a car body with nice paint, but the engine and brakes are missing or don't work. – PaulMcKenzie May 06 '22 at 21:01
  • After this: `receipt* head = NULL;` why are you doing also: `head = new receipt;`? As mentioned, you don't have any constructor nor defaults for receipt so there are random values in price and link... You should just use insert for adding new elements – KIIV May 06 '22 at 21:02
  • @PaulMcKenzie It's a car with a nice paint, an efficient engine and powerful brakes. – ChaoCius May 06 '22 at 21:04
  • Unrelated: It looks like you need to take more care with the questions you are asking. None of your 5 questions have been received positively and fairly soon the server's rate limiter algorithm will kick in and will stop accepting new questions. A couple of the questions look like they could be cleaned up and become positive contributions to the site. Don't delete them. Deleted questions A) can't help anyone and be voted up and B) deleted questions seem to count against you even more. – user4581301 May 06 '22 at 21:07
  • 0xCDCDCDCD is uninitialized heap memory: [https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations](https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations) – drescherjm May 06 '22 at 22:25

2 Answers2

2

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; }
};
pm100
  • 48,078
  • 23
  • 82
  • 145
1

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 aggregate 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 the qualifier const:

void printReceipt( const receipt* n);

and the output of blanks:

cout<<n->price<<'\t'<<" ";
              ^^^^^^^^^^^^

in fact has no effect due to the next line

cout<<endl;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335