c ++ 我是否需要手动删除指向另一个具体类型的 void* 指针?

c++ do I need to manually delete a void* pointer which is then pointing to another concrete type?

本文关键字:类型 另一个 void 指针 是否 删除      更新时间:2023-10-16

假设我有一个指针void* p,那么经过一些函数传入和传出之后,假设p现在指向int。那么我需要手动删除delete static_cast<int*>(p)吗?

在大多数地方,人们说delete只有在有new时才会发生。但在这种情况下,它不是,而是C++本身记得释放该记忆吗?

这完全取决于您指向的int是如何分配的,您只deletenew的内容。


正确(intnew'd(:

int* a = new int;
void* p = a;
//somewhere later...
delete static_cast<int*>(p);

错误(自动管理int(:

int a = 0;
void* p = &a;
//somewhere later...
delete static_cast<int*>(p);

回答注释代码,执行以下操作:

int* a = new int; 
void* p = a; 
delete p;

永远不行。你永远不应该通过void*delete,这是未定义的行为。


旁注:在现代C++中,您真的不应该使用newdelete,坚持使用智能指针或标准容器。

简短的回答是:"视情况而定"。

在大多数地方,人们说delete只有在有new时才会发生。

到目前为止,确实如此。 为了避免浪费资源并确保正确调用所有析构函数,每个new都必须在某处通过delete进行平衡。 如果你的代码可以遵循多个路径,你必须确保每个路径都调用delete(如果调用delete是合适的(。

当抛出异常时,可能会变得棘手,这就是为什么现代C++程序员通常避免使用newdelete的原因之一。 相反,他们使用智能指针std::unique_ptrstd::shared_ptr以及帮助程序模板函数std::make_unique<T>std::make_shared<T>(请参阅 SO 问题:什么是智能指针,何时应该使用智能指针?(来实现一种称为 RAII(资源获取即实例化(的技术。

但在这种情况下,它不是...

请记住,这句话...当存在指针指向的对象而不是指针本身的new引用对象时。请考虑以下代码...

int *a = new int();
void *p = a;
if (SomeTest())
{
delete a;
}
else
{
a = nullptr;
}
// This line is needed if SomeTest() returned false
// and undefined (dangerous) if SomeTest() returned true
delete static_cast<int *> (p);

是否需要最后一行代码?

ap都指向的对象是通过调用new创建的delete因此必须调用某些东西。 如果函数SomeTest()返回falsea已设置为nullptr因此对其调用delete不会影响我们创建的对象。 这意味着我们确实需要最后一行代码来正确删除在第一行代码中新出现的对象。

另一方面,如果函数SomeTest()返回true那么我们已经通过指针a为对象调用了delete。 在这种情况下,不需要最后一行代码,实际上可能是危险的。

C++标准规定,在已删除的对象上调用delete会导致"未定义的行为",这意味着任何事情都可能发生。 请参阅 SO 问题:双重删除会发生什么?

C++自己是否记得释放那段记忆?

不用于通过调用new创建的任何内容。 当你调用new时,你是在告诉编译器"我有这个,我会在适当的时候释放该内存(通过调用delete("。

我需要手动删除吗

是:如果需要在此处删除指向的对象,并且void *指针是可用于delete对象的唯一指针

相关文章: