c ++ 我是否需要手动删除指向另一个具体类型的 void* 指针?
c++ do I need to manually delete a void* pointer which is then pointing to another concrete type?
假设我有一个指针void* p
,那么经过一些函数传入和传出之后,假设p现在指向int
。那么我需要手动删除delete static_cast<int*>(p)
吗?
在大多数地方,人们说delete
只有在有new
时才会发生。但在这种情况下,它不是,而是C++本身记得释放该记忆吗?
这完全取决于您指向的int
是如何分配的,您只delete
您new
的内容。
正确(int
new
'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++中,您真的不应该使用new
或delete
,坚持使用智能指针或标准容器。
简短的回答是:"视情况而定"。
在大多数地方,人们说
delete
只有在有new
时才会发生。
到目前为止,确实如此。 为了避免浪费资源并确保正确调用所有析构函数,每个new
都必须在某处通过delete
进行平衡。 如果你的代码可以遵循多个路径,你必须确保每个路径都调用delete
(如果调用delete
是合适的(。
当抛出异常时,可能会变得棘手,这就是为什么现代C++程序员通常避免使用new
和delete
的原因之一。 相反,他们使用智能指针std::unique_ptr
和std::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);
是否需要最后一行代码?
a
和p
都指向的对象是通过调用new
创建的delete
因此必须调用某些东西。 如果函数SomeTest()
返回false
则a
已设置为nullptr
因此对其调用delete
不会影响我们创建的对象。 这意味着我们确实需要最后一行代码来正确删除在第一行代码中新出现的对象。
另一方面,如果函数SomeTest()
返回true
那么我们已经通过指针a
为对象调用了delete
。 在这种情况下,不需要最后一行代码,实际上可能是危险的。
C++标准规定,在已删除的对象上调用delete
会导致"未定义的行为",这意味着任何事情都可能发生。 请参阅 SO 问题:双重删除会发生什么?
C++自己是否记得释放那段记忆?
不用于通过调用new
创建的任何内容。 当你调用new
时,你是在告诉编译器"我有这个,我会在适当的时候释放该内存(通过调用delete
("。
我需要手动删除吗
是:如果需要在此处删除指向的对象,并且void *
指针是可用于delete
对象的唯一指针。
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- C++将一个指针分配给另一个指针时执行的类型检查
- 如何包装一个函数以适应另一个函数的所需类型
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- 我正在尝试将表的地址传递给要在另一个函数中使用的指针,但得到不兼容的指针类型
- 如何构造一个类型特征,可以判断一个类型的私有方法是否可以在另一个类型的构造函数中调用?
- 缺少类型说明符和另一个问题
- 如果一个变量在它之前释放了另一个(相同的数据类型)变量,如何将其分配给内存?
- 如何在类 A 中传递类型名 T 以在另一个类 B 中使用
- 将积分类型的数组作为另一个不相关的积分类型的阵列进行访问的安全且符合标准的方法
- c ++ 我是否需要手动删除指向另一个具体类型的 void* 指针?
- 如何在另一个类中调用类型类的向量?
- 使用 SFINAE 测试是否可以将一个指针类型static_cast到另一个指针类型
- 检查数值类型是否是另一个数值类型的子集
- 无法从派生类型的作用域访问另一个实例的受保护成员
- 另一个:从"常量类型*"到"类型*"的转换无效
- 为什么直接传递"this"指针来存档是一个错误,而另一个相同类型的指针是可以的?
- C++:在另一个类中作为类型类
- 将 std::variant 转换为另一个具有类型子集的 std::variant
- 类的成员是否可以与其类型(另一个类)命名相同的名称