Does deleting void pointer guarantee to delete right size? [duplicate]

感情迁移 提交于 2019-12-01 03:34:42

Deleting through a void* results in undefined behavior, so you are guaranteed nothing.

5.3.5 Delete [expr.delete]

1 The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.
[...]
The operand shall have a pointer to object type, or a class type having a single non-explicit conversion function (12.3.2) to a pointer to object type. The result has type void.78

78) This implies that an object cannot be deleted using a pointer of type void* because void is not an object type.

Emphasis mine.


So even though you said not to say it, the answer is to create some form of smart pointer. It would need to use type-erasure to hide the type externally (allowing the heterogeneous list), but internally keep track of the type it was given and how to delete it. Something much like boost::any.

A void pointer has no type information. If MyClass has a destructor, it will not be called. The compiler needs to know what it is deleting so it can generate the appropriate code. If all of your pointers in the list are of the same type then you should be storing that type in the list, not as void. If the pointers are different types but derive from a common base type, then give that base type a virtual constructor and store pointers of that type instead.

It is not necessary to use a smart pointer, it's just smart.

That being said, there are many other possibilities; the only thing to do is to store the type information along the actual object.

class Holder {
public:
    template <typename T>
    explicit Holder(T const volatile* t):
        _data(static_cast<void const volatile*>(t)),
        _delete(&Delete<T>)
    {}

    void apply() { _deleter(_data); }

private:
    typedef void (*Deleter)(void const volatile*);

    template <typename T>
    static void Delete(void const volatile* p) {
        delete static_cast<T const volatile*>(p);
    }

    void const volatile* _data;
    Deleter _deleter;
};

And now:

std::list<Holder> owningList;

owningList.push_back(Holder(somePointer));

for (Holder& h: owningList) { h.apply(); }
Scott Earle

The correct answer to this question is of course 'no'

Edit: asked to provide more information, even though I already did in a comment to the question, the deletion of a void* is undefined, and this question is another way of asking this one: Is it safe to delete a void pointer? - see the answers in there for details.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!