使用 void 指针删除在堆中分配的变量是一件坏事吗?
is deleting a variable allocated in heap using void pointer a bad thing?
这段代码有问题吗?
我的意思是删除语句。
int *x = new int;
*x = 13;
void *ptr = x;
delete (int *)ptr;
这段代码没有任何问题,堆上分配的所有内存都是免费的,无论是删除 ptr
还是 x
但不是两者都删除。两个指针都指向内存中的同一个地址,所以这完全没问题;也可以安全地设置 free'd pointers = 0!
#include <iostream>
int main()
{
int* x = new int;
*x = 13;
void* ptr = x;
std::cout << ptr << '\n'; //prints same address
std::cout << x << '\n'; //prints same address
delete (int*)ptr;
//delete x;
ptr = 0;
}
您没有在代码中的 void
指针上调用 delete
。在删除之前,您正在将其变回 int *
。
进行转换 int *
-> void *
-> int *
保证返回 int 指针的原始值。因此,您基本上是在 new
返回的相同值上调用 delete
。这就是你应该做的。
如果你这样做,问题会有所不同
int *x = new int;
void *ptr = x;
delete ptr;
这里 delete
不知道 ptr
实际上应该指向一个 int
,并且无法调用任何属于 int
的析构函数。在 int
的情况下,析构函数可能什么都不做,所以我不能肯定地说代码是无效的,也许更精通 c++ 的人可以参与进来?但是对于其他具有真正析构函数的数据类型,这肯定是个问题。
结尾的小评论:避免new
/delete
。使用智能指针和容器类。仅使用 new
/delete
作为如何编写智能指针的练习。
即使您使用的是 explicit type conversion, the rules for static_cast
apply. The relevant rule is in point 10 of the static_cast
page @ cppreference.com:
Conversion of any pointer to pointer to void and back to pointer to the original (or more cv-qualified) type preserves its original value.
在您的例子中,您从指向 int
的指针开始。当您初始化 ptr
时,您将其转换为指向 void
的指针。您在 delete
语句中转换回指向 int
的指针。这保留了原始值,这意味着 (int *)ptr
和 x
计算出相同的地址(并且具有相同的类型),因此
delete (int *)ptr;
和
delete x;
是等价的。 (我还要添加
delete static_cast<int*>(ptr);
自从养成了使用 static_cast
等人的习惯后就进入了列表。而不是 C 风格的转换可以让你在未来省去麻烦。)
这段代码有问题吗? 我的意思是删除语句。
int *x = new int;
*x = 13;
void *ptr = x;
delete (int *)ptr;
这段代码没有任何问题,堆上分配的所有内存都是免费的,无论是删除 ptr
还是 x
但不是两者都删除。两个指针都指向内存中的同一个地址,所以这完全没问题;也可以安全地设置 free'd pointers = 0!
#include <iostream>
int main()
{
int* x = new int;
*x = 13;
void* ptr = x;
std::cout << ptr << '\n'; //prints same address
std::cout << x << '\n'; //prints same address
delete (int*)ptr;
//delete x;
ptr = 0;
}
您没有在代码中的 void
指针上调用 delete
。在删除之前,您正在将其变回 int *
。
进行转换 int *
-> void *
-> int *
保证返回 int 指针的原始值。因此,您基本上是在 new
返回的相同值上调用 delete
。这就是你应该做的。
如果你这样做,问题会有所不同
int *x = new int;
void *ptr = x;
delete ptr;
这里 delete
不知道 ptr
实际上应该指向一个 int
,并且无法调用任何属于 int
的析构函数。在 int
的情况下,析构函数可能什么都不做,所以我不能肯定地说代码是无效的,也许更精通 c++ 的人可以参与进来?但是对于其他具有真正析构函数的数据类型,这肯定是个问题。
结尾的小评论:避免new
/delete
。使用智能指针和容器类。仅使用 new
/delete
作为如何编写智能指针的练习。
即使您使用的是 explicit type conversion, the rules for static_cast
apply. The relevant rule is in point 10 of the static_cast
page @ cppreference.com:
Conversion of any pointer to pointer to void and back to pointer to the original (or more cv-qualified) type preserves its original value.
在您的例子中,您从指向 int
的指针开始。当您初始化 ptr
时,您将其转换为指向 void
的指针。您在 delete
语句中转换回指向 int
的指针。这保留了原始值,这意味着 (int *)ptr
和 x
计算出相同的地址(并且具有相同的类型),因此
delete (int *)ptr;
和
delete x;
是等价的。 (我还要添加
delete static_cast<int*>(ptr);
自从养成了使用 static_cast
等人的习惯后就进入了列表。而不是 C 风格的转换可以让你在未来省去麻烦。)