プログラムの終了時に Visual C++ ランタイムがオブジェクトを破棄するタイミングに関連する、やや厄介な問題に出くわしました。
特定の状態への参照が有効であることを確認するために使用されるクラスがあります。未知の期間、状態を保存する必要があります。この間、状態は破棄される可能性があり、使用できませんshared_ptr
。だから私は使う
class MyClass
{
private:
static std::list<MyClass*> make_list();
static std::list<MyClass*> refed_list;
static void StateClosed(B* state);
public:
B* state;
MyClass(B* state);
virtual ~MyClass();
bool still_valid() const;
};
の各インスタンスはMyClass
、自身をコンストラクターに追加refed_list
し、デストラクターで自身を削除します。カプセル化された状態が閉じている場合、MyClass
に通知さrefed_list
れ、カプセル化インスタンスをチェックし、そのポインタを無効にします。これは実際には関係ありません。重要なことは、a を使用してstatic list
おり、コンストラクター/デストラクタでこのリストにアクセスすることです。が定義さrefed_list
れているファイルで初期化します。MyClass
さて、問題..私のプログラムがランタイムを閉じると、refed_list
ある時点でランタイムがクリーンアップされ、その後、のインスタンスがクリーンアップされ、MyClass
それらのデストラクタが呼び出されます。refed_list
次に、すでにクリーンアップされているものにアクセスしようとします。これにより、反復子が正しくなくなり、未定義の動作が発生します。この場合は、デバッグ アサーションの失敗です。
この問題を回避する方法はありますか? 異なるコンパイル単位のどの順序オブジェクトが破棄されるかを指定できるとは思えませんが、refed_list
まだ有効かどうかを確認する方法はありますか? 現時点では、動作するかどうかを確認refed_list.size() == 0
していますが、これの動作も未定義です (と思いますか?)。