遍历列表时获得线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)

问题描述 投票:-3回答:1

[当我尝试遍历列表以搜索特定节点时,出现此错误-线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)。我从头开始编写List类。这是我的List类,也是我为支持它而编写的所有其他类。

struct ItemInfo{
    double Itemprice = 0;
    int Itemamount = 0;
};

class List;
class Iterator;

class Node
{

public:
    Node(map<string, ItemInfo> temp, string element);
private:
    string name;
    map<string, ItemInfo> items; 
    Node* next;
    Node* previous; 


    friend class List;
    friend class Iterator;
};

class List
{
public:
    List();
    void push_back(map<string, ItemInfo> temp, string element);
    void insert(Iterator iter, map<string, ItemInfo> temp, string element);
    Iterator erase(Iterator iter);
    Iterator begin();
    Iterator end();
private:
    Node* first;
    Node* last;
    friend class Iterator;
};

class Iterator
{
public:
    Iterator();
    string get() const;
    map<string, ItemInfo> get_map() const;
    void next();
    void previous();
    bool equals(Iterator other) const;
private:
    Node* position;
    List* container;
    friend class List;
};

Node::Node(map<string, ItemInfo> temp, string element )
{
    this->name = element;
    this->items = temp;
    next = nullptr;
}


List::List()
{
    first = nullptr;
    last = nullptr;
}

void List::push_back(map<string, ItemInfo> temp, string element)
{
    Node* new_node = new Node(temp, element);
    if (last == nullptr) // List is empty
    {
        first = new_node;
        last = new_node;
    }
    else
    {
        new_node->previous = last;
        last->next = new_node;
        last = new_node;
    }
}

void List::insert(Iterator iter, map<string, ItemInfo> temp, string element)
{
    if (iter.position == nullptr)
    {
        push_back(temp, element);
        return;
    }

    Node* after = iter.position;
    Node* before = after->previous;
    Node* new_node = new Node(temp, element);
    new_node->previous = before;
    new_node->next = after;
    after->previous = new_node;
    if (before == nullptr) // Insert at beginning
    {
        first = new_node;
    }
    else
    {
        before->next = new_node;
    }
}

Iterator List::erase(Iterator iter)
{
    Node* remove = iter.position;
    Node* before = remove->previous;
    Node* after = remove->next;
    if (remove == first)
    {
        first = after;
    }
    else
    {
        before->next = after;
    }
    if (remove == last)
    {
        last = before;
    }
    else
    {
        after->previous = before;
    }
    delete remove;
    Iterator r;
    r.position = after;
    r.container = this;
    return r;
}

Iterator List::begin()
{
    Iterator iter;
    iter.position = first;
    iter.container = this;
    return iter;
}

Iterator List::end()
{
    Iterator iter;
    iter.position = nullptr;
    iter.container = this;
    return iter;
}

Iterator::Iterator()
{
    position = nullptr;
    container = nullptr;
}

string Iterator::get() const
{
    return position->name;
}

map<string, ItemInfo> Iterator::get_map() const{
    return position->items;
}

void Iterator::next()
{
    position = position->next;
}

void Iterator::previous()
{
    if (position == nullptr)
    {
        position = container->last;
    }
    else
    {
        position = position->previous;
    }
}

bool Iterator::equals(Iterator other) const
{
    return position == other.position;
}

而且我还有另一个班级可以帮助我填写此列表,

class inventory
{

public:

    //constructor to read frmo file
    inventory();
    //function to add items in map
    void iter();
    //last store item entered
    void viewInventory();
    //get list
    List get_list();


private:
    List stores;
};

inventory::inventory(){
    //read from file function
    ifstream read;
    string line;
    string::size_type idex = 4;
    string temp;
    int count = 0;
    ItemInfo enter;
    map<string, ItemInfo> tempMap;
    read.open("/Users/vibhorsagar/Desktop/CovidProject/CovidProject/walmartList.txt");
    if(!read.is_open()){
        cout<<"Error"<<endl;
    }else {
        while (!read.eof()){
            while(getline(read, line)){
                stringstream in(line);
                while(getline(in, line, '-') && count < 3){
                    if(count == 0){
                        temp = line;
                    }
                    else if(count == 1){
                        try{
                        enter.Itemprice = stod(line, &idex);
                        } catch(std::invalid_argument){
                            continue;
                        }
                    }
                    else if(count == 2){
                        enter.Itemamount = stoi(line);
                    }
                    count++;
                }
                tempMap[temp] = enter;
                count = 0;
            }
        }
        stores.push_back(tempMap, "Walmart");
    }
}

void inventory::viewInventory(){

    cout<<"1) View all stores"<<endl;
    cout<<"2) Specific store"<<endl;
    int choice = 0;
    cin >> choice;
    switch(choice){
        case 1:{
            Iterator iterList = stores.begin();
            while (!iterList.equals(stores.end())){
                cout<< "Store: "<< iterList.get()<<endl;
                for(auto IterMap = iterList.get_map().begin(); IterMap != iterList.get_map().end(); IterMap++){
                    cout<<"Item: "<< IterMap->first<<endl;
                    cout<<"Item Price: "<< IterMap->second.Itemprice<<endl;
                    cout<<"Item Amount: "<< IterMap->second.Itemamount<<endl;
                    //getting Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
                }
                iterList.next();
            }
        }
        case 2:{
            string sName;
            cout<<"Enter store name"<<endl;
            cin>>sName;
            Iterator iter = stores.begin();
            while( !iter.equals(stores.end())){
                if(iter.get() == sName){
                    cout<< "Store: "<< iter.get()<<endl;
                    auto iterMap = iter.get_map().begin(); // Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
                    while ( iterMap != iter.get_map().end()){
                        cout<< "Item: "<< iterMap->first<<endl;
                        cout<< "Item Price: "<< iterMap->second.Itemprice<<endl;
                        cout<< "Item Amount: "<< iterMap->second.Itemamount<<endl;
                        iterMap++;
                     }
                }
                iter.next();
            }
        }

    }
}

List inventory::get_list(){
    return stores;
}

此类基本上是打开一个文本文件并读取其内容并相应地填充列表。我的文本文件包含以下内容-

Marketside Butter Lettuce Salad - 2.98 - 200
Marketside Classic Iceberg Salad - 2.64 - 400
Green Bell Pepper - 0.58 - 1000
Cauliflower - 2.97 - 30
Whole Carrots -  0.92 - 200

因此,库存类的构造函数读取此文件后,便将这些项目放置在地图中,例如

map<string, ItemInfo> tempMap; 
//then after reading the first line the map should fill up like this 
tempMap[Cauliflower] = (2.97, 30)

从文件中读取并填充列表很正常,但是当我尝试在搜索功能中访问并遍历列表时,出现此错误线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)。

这里是我的搜索功能

void SearchItem(string itemName){
    inventory inven;
    Iterator iter = inven.get_list().begin();
    map<string, ItemInfo>::iterator ItemIter ;
    for( iter = inven.get_list().begin(); !iter.equals(inven.get_list().end()); iter.next()){
        for( ItemIter = iter.get_map().begin(); ItemIter != iter.get_map().end(); ItemIter++){ //Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
            if(ItemIter->first == itemName){
                cout<<"Item found"<<endl;
                cout<<"Item in store: "<< iter.get().StoreName<<endl;
                cout<<"Item name: "<< ItemIter->first<<endl;
                cout<<"Item price: "<< ItemIter->second.Itemprice<<endl;
                cout<<"Item amount in store: "<< ItemIter->second.Itemamount<<endl;
            }
            else {
                cout<<"Item not found in any store"<<endl;
            }
        }
    }
}

这是我的主要功能

int main(){
    int n;
    inventory check;
    cout<<"1. Employee"<<endl;
    cout<<"2. Customer"<<endl;
    cin>>n;
    switch(n){
        case 1:{
            cout<<"EMPLOYEE"<<endl;
            cout<<"View Inventory?(Y/N)"<<endl;
            char choice;
            cin>>choice;
            if(choice == 'y' || choice == 'Y' ){
                check.viewInventory();
            }

        }
        case 2:{
            cout<<"CUSTOMER"<<endl;
            cout<<"Choose one option"<<endl;
            cout<<"1. Search by Item name\n"<<"2. Search by Item Price\n"<<"3. Search by Item amount"<<endl;
            int choice =0;
            cin>>choice;
            switch(choice){
                case 1:{
                    cout<<"Search Item"<<endl;
                    string iName;
                    getline(cin.ignore(), iName);
                    SearchItem(iName); // getting Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
                    cout<<"Sort from lowest to highest?"<<endl;
                }
                case 2:{
                    cout<<"Search Price"<<endl;
                    double price;
                    cin>>price;
                    SearchItem(price);
                }
            }

        }
    }
    return 0;
}

这是我现在拥有的。如果有人可以帮助我,我将不胜感激。

c++ xcode iterator c++17 doubly-linked-list
1个回答
0
投票

iter.get_map()按值返回地图的副本;两个调用返回两个不同的对象。而且,这些对象是临时对象,在表达式末尾被销毁。 ItemIter成为一个悬空的迭代器-迭代器已损坏的容器。任何使用它的尝试都表现出不确定的行为。

© www.soinside.com 2019 - 2024. All rights reserved.