私のプロジェクトで奇妙な動作が見られます。状況は次のとおりです。オブジェクトのコンストラクタへのポインタを指定すると、オブジェクトが破棄されます
- 私はオブジェクトを持っています。
Victim
に、ポインタ変数、コンストラクタ、デストラクタが含まれています。 - 私は別のオブジェクトを持っています。
Perpetrator
を呼び出し、コンストラクタがVictim
オブジェクトを受け入れ、ポインタ変数を内部の具体的な変数にコピーします。 Victim*
を作成し、new
でオブジェクトを作成した後、Perpetrator
からPerpetrator(*victim)
に渡してください。Perpetrator
のコンストラクタが終了すると、Victim
のデストラクタが呼び出され、オブジェクトが削除されます。
問題は、poor
が建設プロセス中に完全に破壊されたVictim
の唯一のコピーです。最後に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)
0/3/5の規則が壊れています。 'double * pointer;'はおそらく単に 'double value;'でなければならないので、メモリ管理はしません。 – Jarod42
例はこのように意図的に書かれています。私は良質なコピーが、はるかに長く使用される予定のオブジェクトを破壊する可能性があることを示したかったのです。 – bayindirh