0

如何释放空指针。

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;

显示错误运算符“删除”,应用于具有未定义行为的 void* 参数,并且很可能不会调用对象的析构函数。

4

3 回答 3

9

你没有delete一个空指针。为什么?因为:

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

您的编译器如何知道指针对象具有哪种类型?因此要调用哪个析构函数?(尽管它可能可以确定要释放多少内存,具体取决于分配机制。)

不要存储 a void*— 而是使用“真实”指针类型。如果您需要“隐藏”真实类型,请考虑使用多态性而不是过时的 C 实践。

于 2013-05-29T09:19:17.113 回答
3

是如何vPtr初始化的?

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

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

于 2013-05-29T09:20:51.753 回答
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.

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

于 2013-05-29T09:24:22.680 回答