C++ HashTable Quadratic Probing Insert method with resize not working?

384 Views Asked by At

This method is supposed to resize the array once the threshold exceeds the predetermined amount of 0.65. The problem is after this is resized the destructor deletes the array with all the newly copied information on it. I don't know how to fix it.

Some of the comments on there are just me brainstorming what the problem might be.


void Hashtable::insert(int value)
{
    int i = 0;
    int key = hash(value);  // hash(value) % N?

    //check load factor to see if it needs to be resized               
    double q = ((double)(currsize+1) / (double)currcapacity); //calculate current threshold

    if ( q >= threshhold) { //if current threshold is >= to 0.65


        int newSize = nextPrime(currcapacity * 2);  //get new size at the next prime number

        Hashtable newtable(newSize); //create a new table; HOW DO I CREATE THIS ON THE HEAP?

    
        for (int j = 0; j < currcapacity; j++) {  //runs through table calling insert to insert new items into table
            if (htable[j] != EmptyBeforeStart && htable[j] != EmptyAfterRemoval) {
                newtable.insert(htable[j]);
            }
        }

        delete[] htable; //delete old table
        
        this->htable = newtable.htable; //re-assign address of htbale to be newtable.htable //THIS ASSINGMENTS GETS DELETED BY THE DESTRUCTOR
        this->currcapacity = newSize; //update capacity

        this->insert(value);   

        //THE PROBLEM IS THAT THE DESTRUCTOR GETS CALLED AND DELETES THE htable BECAUSE THE NEWTABLE HTABLE WAS DECLARED AUTOMAITCALLY NOT ON THE HEAP.
        
    }
    else {

        while (i < currcapacity) {
            if (htable[key] == EmptyBeforeStart || htable[key] == EmptyAfterRemoval) {
                htable[key] = value;
                currsize++;
                return;
            }
            i++;
            key = (hash(value) + 0 * i + 1 * i * i) % (int)currcapacity;
        }
    }
}

1

There are 1 best solutions below

0
paddy On

Your destructor is called because you created a Hashtable object on the stack with this line:

Hashtable newtable(newSize);

That created a temporary table, which you populated, and then it was thrown away (destroyed) before the function returns. But before that happened, you stole its pointer and stored it in the current hash table. That's a big problem, because when that table is destroyed, it's going to try and delete a pointer that was already deleted.

I think you meant:

int *newtable = new int[newSize];
std::fill(newtable, newtable + newSize, EmptyBeforeStart);

However, you will need to change the rehashing part which copies existing values into this. Now, I'm not saying the following is a great design, but without reworking anything else, you could do this:

// Store information about current table before replacing it
int *oldtable = htable;
int oldcapacity = currcapacity;

// Replace the hash table with new empty one
htable = newtable;
currcapacity = newSize;

// Rehash old values
for (int j = 0; j < oldcapacity ; j++) {
    if (oldtable[j] != EmptyBeforeStart && oldtable[j] != EmptyAfterRemoval) {
        insert(oldtable[j]);
    }
}

// Clean up
delete[] oldtable;

See how the above actually replaces the table with the new empty table, but keeps a pointer to the old data. It then calls insert to hash all the old values into the new table. Then when it's finished, that old memory can be released.