Array subscript operator overloading in C++

351 views Asked by At
int &HTable::operator[](const string &key){
    int hashVal = hash(key);
    list<City> citylist = _pht->at(hashVal);
    std::list<City>::iterator it = citylist.begin();
    for (; it != citylist.end(); it++){
        std::cout << "came_inside" << endl;
        City ob = (*it);
        if (ob.city == key){
            return ob.population;
        }
    }
    City newcity(key,0);
    citylist.push_front(newcity);
    _pht->erase(_pht->begin() + hashVal);
    _pht->insert(_pht->begin() + hashVal, citylist);
    return newcity.population;
}

My class is:

class HTable
{
    public:
        HTable( int );

        int &operator[ ]( const string & );
        void print ( ) const;
        int  size  ( ) const;

    private:
        int _size;
        vector< list< City > > *_pht;

        int hash( const string & ) const;
};

My problem is when I try to use this:

HTable fl_cities( n );                      // hash table with n lists

fl_cities["abcd"] = 1000;
fl_cities["abc"] = 111;
fl_cities["abcdefdf"] = 111;

cout << fl_cities["abc"] << endl;    // return 0
cout << fl_cities["abcdefdf"] << endl; // return 0
cout << fl_cities["abcd"] << endl;  // return 0

I don't get expected value, it shows 0 because I am assigning 0 then returning the value. It is suppose to return the pointer and then when I assign the value it should go there but it doesn't work.

I have tried this operator with simple int array and it worked perfect in that case. But in this problem, list inside a vector it doesn't work.

1

There are 1 answers

2
Yakk - Adam Nevraumont On

Your [] does the following:

If hashes the key. It then copies the list of elements at that hash, searches for the key there, returns a reference if it is found, and destroys the copy of the list you created. This returns a dangling reference, access is undefined.

If it fails to find the key in the list, it makes a local entry, copies that entry into the copy of the list, deletes the list in the hash vector aligned with the key, copies the list back into the hash vector, then returns a reference to the local entry. The local entry is then destroyed, as is the copy of the list.

Undefined behaviour results from reading the reference to the local entry you destroyed.

You need to brush up on the difference between values and references, and pay attention to lifetimes and copies.

Change citylist to a reference.

Remove the erase/insert at the bottom of the function.

Return citylist.front().population on the final line.