当我的代码为运行时偶尔会出现这个错误,如何修复?

How can I repair this error that occurs occasionally when my code is running?

有时代码运行到最后没有任何错误,而其他时候它在中间停止并给我这个错误线程 1:EXC_BAD_ACCESS(代码=EXC_I386_GPFLT) 这是它的照片 (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

这肯定是错误的

 char buyAgain;
 while ((buyAgain = 'y' && buyAgain != 'n')) 

您正在尝试测试一个未初始化的变量,但实际上是在给它赋值

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

更重要的是你没有在收据上初始化字段,你应该有一个构造函数,就像这样

struct receipt {
    string name;
    double price;
    receipt* link;
    receipt() { price = 0; link = nullptr; }
};

对于初学者来说,这些行:

receipt* head = NULL;
head = new receipt;

没有多大意义。 operator new 创建类型为 receipt 的未初始化对象(例如,数据成员 link 可以具有不确定的值),这是函数中使用指针时未定义行为的原因。你只需要写:

receipt* head = NULL;

这个while循环的条件:

while ((buyAgain='y' && buyAgain!='n')){

没有意义。 buyAgain 始终设置为 'y' 在此 sub-expression:

buyAgain='y'

你的意思好像是:

while ( buyAgain == 'y' ){

或:

while ( buyAgain != 'n' ){

但是在while循环之前你必须初始化变量buyAgain

char buyAgain = 'y';

由于结构 receipt 是一个集合,因此在函数 insert 中代替这些语句:

receipt* new_name_node = new receipt();
new_name_node->name = new_name;
new_name_node->price = new_price;
new_name_node->link = NULL;

你可以这样写:

receipt* new_name_node = new receipt
{
    new_name, new_price, nullptr
};

注意结构struct linkedListFunctions中声明的处理列表的函数至少要是静态成员函数

函数printReceipt的参数应该有限定符const:

void printReceipt( const receipt* n);

和空白的输出:

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

由于下一行

实际上没有效果
cout<<endl;