0

I have the following union-like struct

struct MyStruct {
    enum {A, B} tag;

    union {
        int option_1;

        struct {
            unordered_map<string, into> map;
            int number;
        }option_2;
    };

    MyStruct(int x) : tag(A) {
        option_1 = x;
    }

    MyStruct(unordered_map<string, int> &map, int x) : tag(B) {
        new (&option_2.map) unordered_map<string, int>(std::move(map));
        option_2.number = x;
    }

    ~MyStruct() {
    // Some code here
    }
};

The unordered_map makes the union non trivial. Since I'm calling new in one of the the constructors I would need to free the memory for the map once I'm done with the struct. So I thought I should call delete in the destructor.

~MyStruct () {
    if (tag == B) {
        delete &option_2.map;
    }
}

But this gives me runtime errors saying I can't call free on the pointer. I then simply tried to free the map by setting the other Union member, and it seemed to work (trying to access the map after the struct goes out of scope results in a seg fault).

~MyStruct () {
    option_1 = 0;
}

My question is why doesn't my first attempt at a destructor work, and is the second attempt at a destructor the best practice here?

botk
  • 1
  • 2
  • 1
    You used placement new, so you cannot call regular `delete`. You'd have to call the destructor explicitly instead – UnholySheep Sep 11 '22 at 17:38
  • @UnholySheep ah I see. After looking into it a bit more, I see that placement new uses memory on the stack. Does this mean there's no need to call the destructor in the first place? – botk Sep 11 '22 at 17:59
  • Placement new uses whatever memory you provide via the argument. And you need to call the destructor, as it won't be called otherwise – UnholySheep Sep 11 '22 at 18:02

0 Answers0