如何释放空指针。
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 *参数,并且很可能不会调用该对象的析构函数。
答案 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.
请注意,这是一个简单的例子,它可以更美观地编写。