【问题标题】:Deleting void pointer after assigning it with original type用原始类型分配空指针后删除它
【发布时间】:2023-03-18 14:27:01
【问题描述】:

下面程序中的空指针是否可以删除。

class Sample
{
    public:
        int intVal;
        float floatVal;
};

main() {
    Sample *samObj = new Sample();
    void *vPtr = samObj;
    delete vPtr;
}

这只是我编写的一个示例程序。实际上,在我的项目中,除了做类似的事情,我别无他法。这个类似的代码在 .h 接口文件中,当我包含这个文件并编译其他组件时,编译器会发出警告消息“警告:删除 'void*' 是未定义的”,但我怀疑是因为我已经分配了 void Sample 对象类型的指针,删除这个指针不安全吗?

【问题讨论】:

  • 可能会在这里找到答案stackoverflow.com/questions/941832/…
  • 在您的示例代码中,您不是在删除vPtr,而是在删除samObj,这很好。
  • 您到底想完成什么?一旦你删除了samObjvPtr 就没有用了,因为你也有效地删除了它。
  • 对不起!!!代码应该是“删除 vPtr”

标签: c++ void-pointers


【解决方案1】:

在 void 指针上调用 delete 是未定义的行为[Ref ]。你根本不应该这样做。您不是在 void 指针上调用 delete,而是在 Sample 类型的指针上调用,这很好。

[参考] C++ 标准:第 5.3.5/3 节:

在第一种选择中(删除 对象),如果是静态类型 操作数与其动态不同 类型,静态类型应为基类 操作数的动态类型的类 并且静态类型应具有 虚拟析构函数或行为是 不明确的。在第二种选择中 (删除数组)如果是动态类型 要删除的对象不同于 它的静态类型,行为是 未定义。

脚注:

这意味着一个对象不能 使用 void* 类型的指针删除 因为没有类型的对象 无效

【讨论】:

  • 谢谢你,Alok...我必须找到另一种方法。实际上,我的项目中的问题非常棘手。我有一个线程,它接受 void * 参数,因此,用户可以将他希望的任何类型传递给线程。他会启动线程并忘记它。现在,我必须小心从用户那里删除分配的内存,但问题是他可以传递任何类型的参数。不确定,如何解决这个问题。
【解决方案2】:

不,以这种方式删除 void 指针是不安全的。编译器应该如何“知道” vPtr 指向的内容?编译器不能;运行时可以,但事实并非如此。

为什么编译器需要“知道” vPtr 指向的内容?调用析构函数并知道要释放多少内存。如果编译器在每次分配时都保留一个标准头,那么释放多少内存可能不是一个大问题。但我想这是留给编译器的一个细节,所以即使在这个部门,结果也会是“未定义”。

【讨论】:

  • 标题具有误导性。看代码; OP 在Sample* 上调用delete,这很好。不知道是笔误还是什么,但代码没有错。
  • 我明白你的意思;是的,删除实际上根本不在 void 指针上。编译器根本不应该抱怨。
  • 对不起!!它是一种类型(一个非常大的错字:))...它应该是“删除 vPtr”。我正在寻找编辑问题的方法。我是 Stackoverflow 的新手
  • @Santosh:没问题,我帮你搞定了。帖子底部有一个编辑按钮。
【解决方案3】:

代码显示正常。 只要你记得将void *vPtr 指向 null 或任何存在的东西。

真正的问题是当你删除void *vPtr时,因为编译器不知道你要删除什么对象,它不知道可以释放多少内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-28
    • 2013-07-28
    • 2011-09-14
    • 1970-01-01
    • 2011-12-17
    • 2016-10-03
    • 1970-01-01
    • 2013-03-04
    相关资源
    最近更新 更多