Search code examples
c++c++11pointersdereference

When dereferencing a vector to set a value the entire vector gets overwritten


I am declaring a vector and a base element that essentially means the slot is open in my header file:

template <typename K, typename V>
class Map_Hash
{
private:
    vector<KeyValue<K,V>*> *hashTable;
    KeyValue<K,V> *baseElt;
}

I instantiate them in my constructor:

template <typename K, typename V>
Map_Hash<K,V>::Map_Hash(int M, K baseKey, V baseValue)
{
    this->M = M;
    baseElt = new KeyValue<K,V>(baseKey, baseValue);
    hashTable = new vector<KeyValue<K,V>*>(M, baseElt);
}

Now when I am trying to write new values to them I am doing it like this:

template <typename K, typename V>
void Map_Hash<K,V>::add(K key)
{
    KeyValue<K,V> elt(key);
    int hashVal = getHashVal(elt);
    (*(*hashTable)[hashVal]) = elt;
}

There is a little more logic here to deal with the value already being in the table but I think it might just crowd up what is important. When the line (*(*hashTable)[hashVal]) = elt; is executed my entire vector is overwritten with the elt and all I want is just the index I have provided. Also what happens which I really cam't make sense of, but my baseElt also gets overwritten with this value. I'm sure it has something to do with how I am handling the pointers I am new to c++ so any help would be very much appreciated.


Solution

    • Don't use pointers.
    • Don't use new.
    • Use an initializer list in your constructor.

    Get rid of your pointers and make sure M and baseElt are before hashTable:

    template <typename K, typename V>
    class Map_Hash
    {
    private:
        int M;
        KeyValue<K,V> baseElt;
        vector<KeyValue<K,V>> hashTable;
    }
    

    Use an initializer list in your constructor:

    template <typename K, typename V>
    Map_Hash<K,V>::Map_Hash(int M, K baseKey, V baseValue) :
        M{ M },
        baseElt{ baseKey, baseValue },
        hashTable{ M, baseElt }
    {
    }
    

    Then just add a new value to your vector:

    template <typename K, typename V>
    void Map_Hash<K,V>::add(K key)
    {
        KeyValue<K,V> elt{ key };
        int hashVal = getHashVal(elt);
        hashTable[hashVal] = elt;  // This will fail if hashVal is too big for the size of your vector!
    }
    

    You might want to rename M, that's a seriously bad name. I am also not sure why you'd want to construct your vector that way. Or use one at all when creating a hash map. There are already plenty of containers for storing keyvalues with hashing like std::unordered_map in the standard. All in all your code smells.

    Your question might be an XY Problem.