0

I'm having trouble figuring out the destructor for my hashTable class, the destructor is like this:

template <typename ElementType>
HashSet<ElementType>::~HashSet() noexcept
{
    for (unsigned int i=0;i<hashCapacity;i++)
    {
        Node* current = hashTable[i];
        while(current != nullptr)
        {
            Node* entry = current;
            current = current->next;
            delete[] entry;
        }
    }
    delete[] hashTable;
}

No matter I use either delete[] or delete, it gives me either double-free errors or segmentation fault.

The class template is below:

template <typename ElementType>
class HashSet : public Set<ElementType>
{
public:
    // The default capacity of the HashSet before anything has been
    // added to it.
    static constexpr unsigned int DEFAULT_CAPACITY = 10;

    // A HashFunction is a function that takes a reference to a const
    // ElementType and returns an unsigned int.
    using HashFunction = std::function<unsigned int(const ElementType&)>;

public:
    // Initializes a HashSet to be empty so that it will use the given
    // hash function whenever it needs to hash an element.
    explicit HashSet(HashFunction hashFunction);

    // Cleans up the HashSet so that it leaks no memory.
    ~HashSet() noexcept override;

    // add() adds an element to the set.  If the element is already in the set,
    // this function has no effect.  This function triggers a resizing of the
    // array when the ratio of size to capacity would exceed 0.8, in which case
    // the new capacity should be determined by this formula:
    //
    //     capacity * 2 + 1
    //
    // In the case where the array is resized, this function runs in linear
    // time (with respect to the number of elements, assuming a good hash
    // function); otherwise, it runs in constant time (again, assuming a good
    // hash function).  The amortized running time is also constant.
    void add(const ElementType& element) override;

Where my add function and default constructor implementation is like this:

template <typename ElementType>
HashSet<ElementType>::HashSet(HashFunction hashFunction)
    : hashFunction{hashFunction}
{
    hashCapacity = DEFAULT_CAPACITY;
    hashSize = 0;
    hashTable = new Node* [hashCapacity];
    for (int i=0;i<hashCapacity;++i)
    {
        hashTable[i] = nullptr;
    }
}

template <typename ElementType>
void HashSet<ElementType>::add(const ElementType& element)
{
    if (contains(element)==false)
    {
        if ((hashSize/hashCapacity) > 0.8)
        {

        }
        else 
        {
            unsigned int index = hashFunction(element) % hashCapacity;
            hashSize += 1;
            Node* add = new Node;
            add->next = nullptr;
            add->value = element;
            if (hashTable[index]==nullptr)
            {
                hashTable[index] = add;
            }
            else
            {
                Node* addNode = hashTable[index];
                while(addNode->next != nullptr)
                {
                    addNode = addNode->next;
                }
                addNode->next = add;
            }
        }
    }
}

Note: that resize hashtable part is incomplete because I'm examining the functionality for my hash table to hold a small amount of value first.

ablmmcu
  • 153
  • 2
  • 14
Alex
  • 157
  • 6
  • 2
    First `delete[] entry;` is wrong. It was not array-allocated, it should not be array-deleted. Second, if you think the destructor for `Node` isn't important enough to include here, think again. – WhozCraig May 20 '21 at 08:16
  • Why are you re-inventing the wheel anyway, there's [`std::unordered_set`](https://en.cppreference.com/w/cpp/container/unordered_set) already. – Aconcagua May 20 '21 at 08:17
  • Side note: booleans are usually checked by `if(condition)` or in negated variant `if(!condition)`. – Aconcagua May 20 '21 at 08:23
  • 1
    Create a [mcve] – eerorika May 20 '21 at 08:27
  • You need to use [the Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three), but it's hard to guess if this is the source of segfault without any `main()` function. – Yksisarvinen May 20 '21 at 08:28

0 Answers0