将对象的指针提供给构造函数会导致对象被破坏
Providing a pointer of an object to a constructor causes object to be destructed
我在一个项目中看到了一种奇怪的行为。情况如下:
- 我有一个对象。让我们调用包含指针变量的
Victim
,一个构造函数和破坏者。 - 我有另一个对象,让我们调用
Perpetrator
,其构造函数接受Victim
对象,然后将指针变量复制到内部的混凝土变量。 - 我创建一个
Victim*
,并使用new
创建对象,然后通过Perpetrator(*victim)
。
将其提供给 - 当
Perpetrator
的构造函数完成时,Victim
的destructor被称为并删除对象。
Perpetrator
问题是Victim
的唯一副本,即poor
在施工过程中被完全破坏。通过delete poor
在末尾整理程序将导致双重错误。
在C 98/11,GCC 4.8.5、7.X和LLVM Clang中,行为是一致的,因此必须很好地定义它。这种行为叫什么,它的语义是什么?
我的理论是,因为constructor
接受了一个具体的对象,因此被视为复制,因此在完成constructor
/function
时会破坏它。
由于我赞美PoC||GTFO
,这是代码:
澄清:该示例是故意编写的,因为它是一个更复杂但非裸露和管理良好的数据结构复杂的简化模型。删除所有必要的位,使其看起来像是一个可怕的代码。在真实代码中,Victim
是一个长期的数据存储,Perpetrator
是用于处理上述数据的临时存储变量。
#include <iostream>
using namespace std;
struct Victim
{
double* pointer;
Victim ()
{
this->pointer = new double(42.2);
}
~Victim ()
{
cout << "Destructor of the Victim is called." << endl;
delete this->pointer;
}
};
struct Perpetrator
{
double concrete;
Perpetrator (Victim victim)
{
concrete = *(victim.pointer);
}
};
int main ()
{
Victim* poor = new Victim();
Perpetrator cruel(*poor);
cout << cruel.concrete << endl;
}
样本输出:
./destructor_test
Destructor of the Victim is called.
42.2
Perpetrator (Victim victim)
-通过value 传递对象。意味着它必须是(复制)构造,然后在呼叫完成时被破坏。
实际上,根本不需要使用new
。这个:
int main ()
{
Victim poor;
Perpetrator cruel(poor);
cout << cruel.concrete << endl;
}
的行为类似。您将看到两个结构和两个破坏。您的原始代码不显示第二个,因为您的示例泄漏。
通过参考:
通过受害者struct Perpetrator
{
double concrete;
Perpetrator (Victim& victim)
{
concrete = *(victim.pointer);
}
};
受害者将构建&amp;
这是您想实现的目标吗?
using namespace std;
struct Victim
{
double* pointer;
Victim ()
{
this->pointer = new double(42.2);
}
~Victim ()
{
cout << "Destructor of the Victim is called." << endl;
delete this->pointer;
}
};
struct Perpetrator
{
double concrete;
Perpetrator (Victim *victim)
{
concrete = *(victim->pointer);
}
~Perpetrator ()
{
cout << "Destructor of the Perpetrator is called." << endl;
}
};
int main ()
{
Victim* poor = new Victim();
Perpetrator cruel(poor);
cout << cruel.concrete << endl;
delete poor;
}
输出:42.2
受害者的毁灭者被称为。
调用肇事者的驱动器。
相关文章:
- 对象指针在c++中是如何工作的
- C++ 对象指针数组的复制构造函数
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 正确初始化和销毁对象指针的C++数组?
- 如何深度复制链表对象指针
- 对象指针 c++ 的全局向量错误
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- 静态对象指针
- 正在将对象指针数组初始化为NULL
- 如何使用条件表达式返回对象指针?
- std::flush可以用于将对象指针转换为其封闭数组指针吗
- 使用C对象指针构建PyObject*
- 如何在使用对象指针时访问成员函数
- 静态强制转换允许转换对象指针,但不允许转换整数
- C++ abort() 在函数内的抽象类对象指针调用上
- 指向函数的对象指针
- 访问指向对象指针向量的指针的第一个元素?
- 如何将对象/指针正确存储到 Qlist 中
- 对象指针打印结果以相反的顺序进行