freeing a void pointer

前端 未结 3 574
故里飘歌
故里飘歌 2021-01-28 14:47

How to free a void pointer.

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

struct vStruct sObj;
struct vStruct *sObjNew = sObj;

delete sObjNew-&         


        
相关标签:
3条回答
  • 2021-01-28 15:07

    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.

    0 讨论(0)
  • 2021-01-28 15:08

    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.

    0 讨论(0)
  • 2021-01-28 15:23

    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.

    0 讨论(0)
提交回复
热议问题