0

So, I created my own constructors for structs that used pointers thinking I'd do a great memory management, when actually I'm not. When I used the version 1 of hashF, I got the double free error. When I used the version 2, I didn't. Could you please explain to me why? I'm still learning to manage the memory properly.

struct Vect {
    int* arr;
    int sz=0;

    Vect(int n = 5){
        this->sz = n;
        arr = new T[n];
    }

    ~Vect()
    {
        delete[] arr;
    }
};

struct Node
{
    bool empty = true;
    uint32_t ckey;
    Vect<int> positions;

    Node(uint32_t key = 0)
    {   
        if(key != 0){
            empty = false;
            ckey = key;
        }
    }

};

struct HT
{
    Node* arr;
    int capacity;
    int numele=0;
    float ocupation=0;

    HT(int n)
    {
        arr = new Node[n];
        capacity = n;
    }

    ~HT()
    {
        delete[] arr;
        arr = nullptr;
    }
};

version 1:

int hashF(uint32_t ckey, Node* &nodearr, int mode=0)
    {
        uint p0 = ckey % capacity;
        for(int i=0; i<capacity; i++)
        {
            int pos = (p0 + i) % capacity;
            Node N = nodearr[pos];
            bool a = N.empty;
            if(mode == 0)
            {
                if(N.empty == true)
                    return pos;
            }else
            {
                if(!((!N.empty) && (N.ckey != ckey)))
                    return pos;
            }
        }
        return -1;
    }

version 2:

int hashF(uint32_t ckey, Node* &nodearr, int mode=0)
    {
        uint p0 = ckey % capacity;
        for(int i=0; i<capacity; i++)
        {
            int pos = (p0 + i) % capacity;
            Node *N = &nodearr[pos];
            bool a = N->empty;
            if(mode == 0)
            {
                if(N->empty == true)
                    return pos;
            }else
            {
                if(!((!N->empty) && (N->ckey != ckey)))
                    return pos;
            }
        }
        return -1;
    }
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • 1
    To summarize the above link, your destructors are fine. But if you declare the destructor, then you're responsible for declaring some other functions as well, which you've neglected to do. – Silvio Mayolo Jul 02 '21 at 02:06
  • 1
    `new T[n];` should be `new int[n];` – Barmar Jul 02 '21 at 02:07
  • 1
    Or `Vect` should be a template (as you seem to expect in `Node`). – Barmar Jul 02 '21 at 02:07
  • 1
    I'm voting to reopen because just closing it as a dupe of the "Rule of 3" question doesn't properly answer the OP's needs in sufficient detail. – selbie Jul 02 '21 at 02:10
  • 1
    If you are coming in from a language where objects default to being references, know that C++ defaults to objects being values, so `Node N = nodearr[pos];` creates a new `Node` named `N` that is a copy of `nodearr[pos]`. Copying can make a huge difference when an object manages a resource. The copying needs to properly protect the resource. – user4581301 Jul 02 '21 at 02:25
  • 1
    @OP Your `struct Vect` and `struct HT` suffer from the same mistake in the **Managing resources** section of the link for the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). You could simply go to the duplicate link, search for **Managing resources**, and presto, there are your faulty classes, as if by magic. – PaulMcKenzie Jul 02 '21 at 02:44

0 Answers0