これは簡単な質問だと思いますが、複雑なレガシーコードを見つめていると、森の木々が見えなくなります。このアプリケーションは数日間実行され、終了すると失敗します(もちろん、短いジョブでは失敗しません!)SEGVの疑いがあります。
以下のいくつかの擬似コードを使用してケースを簡略化しました(うまくいけば、正しく理解できます)。
人間の言葉で言えば:私は、単純なクラスABCへのポインターのベクトルを含む多くのものを含むクラスXYZを持っています(それが単純であると仮定しましょう)。これらのポインタは、XYZのデストラクタで削除されます。デストラクタが行うのはそれだけです。
次に、デストラクタのない2つの単純な仮想メソッドを持つ単純な基本クラスTheBaseがあります。
最後に、TomとDick(TheBaseから派生)とHarry(TheBaseから派生ではない)の3つのクラスがあります。これら3つはすべて、XYZオブジェクトへのconst参照から構築されています。したがって、XYZオブジェクトへのconst参照があります。また、デストラクタもありません。
メインでは、boost :: shared_ptrは、Tom、Dick、およびHarryオブジェクトごとに1つずつ定義されています。次に、XYZオブジェクトが作成されます。次に、そのXYZオブジェクトは、Tom、Dick、およびHarryオブジェクトへのconst参照として渡されます。その後、たくさんのことが起こり、メインが終了します。
では、これらすべてが範囲外になるとどうなりますか?特にXYZオブジェクト?これは正しく処理されますか?何かが複数回削除されるようです。
// A simple class (let's assume it is!)
class ABC
{
// unimportant stuff.
}
// class XYZ has an array of ABC objects. All the destructor does is delete those objects.
class XZY
{
public:
XYZ(vector<string> v1,
vector<string> v2,
vector<string> v3 );
virtual ~XYZ(){
for ( i = 0; i < n, i++ ){
delete my_abcs[i];
}
}
private:
vector <ABC*> my_abcs
// lots of other methods & members
}
// Simple base class with only 2 simple virtual methods
class TheBase
{
public:
virtual void minor_func1();
virtual void minor_func2();
}
// A class derived from base class. Constructs with a const reference to an XYZ class.
class Tom:TheBase
{
public:
Tom( const XYZ & xyz )
private:
const XYZ & my_xyz;
// lots of other methods & members
}
Tom::Tom(const XYZ & xyz):my_xyz(xyz){
...
}
// Another class derived from base class. Constructs with a const reference to an XYZ class.
class Dick:TheBase
{
public:
Dick( const XYZ & xyz )
private:
const XYZ & my_xyz;
// lots of other methods & members
}
Dick::Dick(const XYZ & xyz):my_xyz(xyz){
...
}
// A class NOT derived from base class but still constructs with a const reference to an XYZ class.
class Harry:TheBase
{
public:
Harry( const XYZ & xyz )
private:
const XYZ & my_xyz;
// lots of other methods & members
}
Harry::Harry(const XYZ & xyz):my_xyz(xyz){
...
}
main (...){
...
boost::shared_ptr <Tom> a_tom;
boost::shared_ptr <Dick> a_dick;
boost::shared_ptr <Harry> a_harry;
...
XYZ a_xyz( ... );
a_tom.reset( new Tom( a_xyz) );
a_dick.reset( new Dick( a_xyz) );
a_harry.reset( new harry( a_xyz) );
...
}