释放一个无效指针

时间:2013-05-29 09:17:43

标签: c++ pointers void-pointers

如何释放空指针。

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;

显示错误操作符'delete',应用于具有未定义行为的void *参数,并且很可能不会调用该对象的析构函数。

3 个答案:

答案 0 :(得分:9)

你没有delete一个无效指针。为什么?这是因为:

  

'delete',应用于void*参数具有未定义的行为,并且很可能不会调用该对象的析构函数。

您的编译器如何知道指针对象具有哪种类型?那么哪个析构者要打电话? (虽然它可能决定要释放多少内存,具体取决于分配机制。)

不存储void* - 改为使用“真实”指针类型。如果您需要“隐藏”真实类型,请考虑使用多态而不是过时的C语言。

答案 1 :(得分:3)

vPtr是如何初始化的?

  • 如果它指向结构不拥有的数据,则不得销毁它。
  • 如果它指向使用malloc创建的数据,则应致电free
  • 如果它指向使用new创建的数据,则在调用delete以允许调用正确的析构函数之前,您需要将其强制转换为正确的(或兼容的)类型。

请注意,您的示例代码不会编译,但建议vPtr根本没有初始化。您必须在您创建的所有vPtr个实例中初始化vStruct。试图释放未初始化的vPtr会产生不明确的后果,但可能会崩溃。

答案 2 :(得分:3)

您不应删除void指针。 delete适用于特定类型(编译器知道,应该调用哪个析构函数 - 如错误消息中所述)。

如果你想在你的结构中保留未指定的类型,你必须以某种方式包装它。

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.

请注意,这是一个简单的例子,它可以更美观地编写。