Hacker News
points by dragontamer 4 days ago | 0 comments
> There's virtually no sensible case where the person calling free() doesn't know the size of the allocation

Polymorphism in C++?

A* blah = new B();

[–] 1718627440 4 days ago
You already need a virtual destructor here anyway, because it needs to know about the actual type B, which includes it's size.
[–] dragontamer 4 days ago
In C++, the destructor doesn't call free() because the destructor doesn't know if it's on the stack or heap.

Consider:

    void f(){
        A* tmp = someFunction(stuff);
        foo(tmp);
        delete tmp;
    }

    void g(){
        A tmp; // destructor will be called, but no free/delete
    }
What is the size of A? Answer: you never know in C++ due to polymorphism. It might be a B or other subclass. It is truly a variable length operation.

And secondly, the destructor cannot tell if it's f() or g()

[–] adev_ 4 days ago
> What is the size of A? Answer: you never know in C++ due to polymorphism. It might be a B or other subclass. It is truly a variable length operation.

You could easily go around it.

The compiler knows when creating the destructor for B.

In your example, to have correct C++, you need to have declared a virtual destruct-or for B. You could encode the size of B in a static offset from the virtual destructor or simply as a return value from it.

This is not how it is done now, mainly because how free was designed in C.

free() design is a terrible mistake. Probably one of the worst design mistake of C with the null terminated / no-length specified string and the preprocessor.

[–] dgrunwald 4 days ago
But it's possible for `delete tmp;` to call a user-defined `operator delete()` in the derived class! https://godbolt.org/z/hvePa6jMP

The way this works under the hood is that every polymorphic class has two destructors (so two destructor entries in the vtable): the "complete object destructor" is the ~A() you know from C++, and then there's also the "deleting destructor" which combines ~A() + delete.

So the deleting destructor can call free() while knowing the derived object size, even for a delete-via-base-class-pointer.

[–] cowlevel 3 days ago
At least in the MSVC implementation, "delete tmp;" calls "operator delete" polymorphically, through a hidden virtual function. I think this is because derived classes may override "operator delete"?