freeing a void pointer

蓝咒 提交于 2019-12-02 16:50:07

问题


How to free a void pointer.

struct vStruct {
    void *vPtr;
    struct vStruct *next;
};

struct vStruct sObj;
struct vStruct *sObjNew = sObj;

delete sObjNew->vPtr; -----------> Is this correct way to delete void pointer
delete sObjNew;

Showing error Operator 'delete', applied to void* argument having has undefined behavior, and most likely does not invoke the object's destructor.


回答1:


You should not delete a void pointer. delete works for specific types (such that compiler knows, which destructor should be called - as stated in error message).

If you want to hold unspecified type in your structure, you have to wrap it somehow.

class DataWrapper
{
public:
    virtual void * GetData() = 0;            
    virtual ~DataWrapper()
    {
    }
};

class MyDataWrapper
{
protected:
    MyData * data;

public:
    MyDataWrapper(MyData * newData)
    {
        data = newData;
    }

    void * GetData()
    {
        return data;
    }

    ~MyDataWrapper()
    {
        delete data;
    }
};

struct vStruct
{
    MyDataWrapper * vPtr;
    struct vStruct *next;

    ~vStruct()
    {
        if (vPtr != null)
            delete vPtr;
    }
};

vStruct sObj;
sObj.vPtr = new MyDataWrapper(new MyData());

// When sObj gets deleted, MyDataWrapper is
// deleted too (thanks to the ~vStruct) and
// in effect, the allocated data is deleted too.

Note, that it's a simple example, it can be written more aesthetically.




回答2:


You do not delete a void pointer. Why? Because:

'delete', applied to void* argument has undefined behavior, and most likely does not invoke the object's destructor.

How would your compiler know which type the pointee object has? And therefore which destructor to call? (Though it can probably determine how much memory to free, depending on the allocation mechanism.)

Do not store a void* — use a "real" pointer type instead. If you need to "hide" the true type, consider employing polymorphism instead of antiquated C practices.




回答3:


How was vPtr initialised?

  • If it points to data the struct doesn't own, you must not destroy it.
  • If it points to data created using malloc, you should call free.
  • If it points to data created using new, you'd need to cast it to the correct (or a compatible) type before calling delete to allow the correct destructor to be called.

Note that your example code won't compile but suggests vPtr is not being initialised at all. You must initialise vPtr in all vStruct instances you create. Attempting to free an uninitialised vPtr would have undefined consequences but would likely crash.



来源:https://stackoverflow.com/questions/16809998/freeing-a-void-pointer

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