“删除此项;”期间发生了什么陈述
What is happening during `delete this;` statement?
请考虑以下代码:
class foo
{
public:
foo(){}
~foo(){}
void done() { delete this;}
private:
int x;
};
以下两个选项中发生了什么(有效吗?):
选项1:
void main()
{
foo* a = new foo();
a->done();
delete a;
}
选项2:
void main()
{
foo a;
a.done();
}
选项1中的第二个delete a;
语句会导致异常或堆损坏吗?
option2会导致异常或堆损坏吗?
delete this;
是允许的,它会删除对象。
您的两个代码片段都有未定义的行为——在第一种情况下,删除已经删除的对象,在第二种情况下删除具有自动存储持续时间的对象。
由于行为是未定义的,所以标准没有说明它们是否会导致异常或堆损坏。对于不同的实现,它可能是任意一种,也可能不是,也可能两者都是,而且每次运行代码时,它可能相同,也可能不相同。
两者都会导致错误。
第一个指针被删除两次,第二个delete
导致错误,而第二个指针被分配在堆栈上,不能被隐式删除(第一次调用析构函数导致错误)。
这个问题已经得到了回答,但我要补充一点,如果你的类确实调用了delete This,那么你也应该将析构函数设为私有的。
这样可以确保只有类可以删除自己。
如果您在上面将析构函数设为私有的,那么两个代码示例都将无法编译。
调用delete this
是个坏主意。无论谁呼叫new
,都应该呼叫delete
。因此出现了其他答复中强调的问题。
此外,在构造对象数组时,可能会出现内存泄漏/未定义行为。
两者都会导致错误,您需要的是:
void main()
{
foo* a = new foo();
a->done();
}
编译器将扩展到下面这样的内容,我希望这能减少删除"this"的混乱。
void __foo_done(foo* this)
{
delete this;
}
void main()
{
foo* a = new foo();
__foo_done(a);
}
另请参阅,成员函数说删除这个是否合法(和道德)?
对于释放内存的上下文,我会非常谨慎。虽然调用"delete this;"将尝试释放与类结构相关的内存,但该操作无法推断原始内存分配的上下文,即,是否从堆或堆栈中分配。我的建议是重新编写代码,以便从外部上下文调用deallocation操作。请注意,这与释放类内部的结构不同,在这种情况下,请使用析构函数。
在这两种情况下,堆都会损坏。当然,你不能在选项2中使用"->"如果左边的值(在本例中为"a")不是指针,选项2中的正确形式将是a.done();但是,是的,如果你试图删除1)已经删除的内容,或者2)本地变量,你应该会得到堆损坏。
调用"delete this"在技术上是有效的,可以释放内存。
编辑我很好奇,实际上试过这个:
class foo
{
public:
foo(){}
~foo(){}
void done() { delete this; }
void test() { x = 2; }
int getx() { return x; }
private:
int x;
} ;
int main(int argc, char* argv[])
{
foo *a = new foo();
a->done();
a->test();
int x = a->getx();
printf("%in", x);
return x;
}
对printf
的调用将成功,并且x
将保持值2
。
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 这C++代码中发生了什么C++(指数函数)
- 哪种方式更快?究竟发生了什么,我们没有看到什么?
- 从"LLONG_MAX 秒"构造 std::chrono::毫秒变量时发生了什么?
- 这个片段中关于 n 在 pc[i] 中的表示发生了什么
- istringstream,num1 和 num2 在这里发生了什么?
- 究竟发生了什么,我们需要在 c++ 中双重调度/访客
- 我是否能够确定在部署一个程序后发生了什么,我在数组末尾写入?
- 这个阶乘程序内部发生了什么?
- C++ - *(int**) 地址?这里发生了什么?
- C++用用户输入在循环中填充 char 数组:输入整个字符串时到底发生了什么?
- 让对象知道它创建的 show 函数中发生了什么
- 这里的矢量数组发生了什么?
- 增加顶级常量指针时发生了什么
- 当另一端将其关闭时,插座发生了什么
- C :我堆栈顶部发生了什么
- 此递归中发生了什么?我需要仅使用递归/无循环来计算和备份
- 这个 std::vector 构造函数中发生了什么
- 编译器认为 int 是一个字符串.发生了什么事情
- 无法运行简单的 std::async 和 std::future 测试程序。错误:"has initializer but incomplete type."发生了什么?