Visual C++ 런타임에서 프로그램이 종료 될 때 개체가 파괴되는 것과 관련된 다소 성가신 문제가 발생했습니다.Visual C++ 런타임 개체 파괴 순서
나는 특정 주에 대한 참조가 유효한지 확인하는 데 사용되는 클래스가 있습니다. 알 수없는 시간 동안 상태를 저장해야하며이 시간 동안 상태가 파괴 될 수 있으며 shared_ptr
을 사용할 수 없습니다. 그래서 MyClass
의 각 인스턴스는 생성자 refed_list
에 자신을 추가하고 소멸자에서 자신을 제거
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
을 확인하고 해당 포인터를 무효화합니다. 이것은 실제로 관련이 없습니다. 중요한 것은 static list
을 사용하고 생성자/소멸자에서이 목록에 액세스한다는 것입니다. MyClass
이 정의 된 파일에서 refed_list
을 초기화합니다.
문제가 .. 내 프로그램이 닫히면 런타임에 refed_list
이 정리되고 그 후에는 소멸자를 호출하여 MyClass
의 인스턴스를 정리합니다. 그런 다음 이미 정리 된 refed_list
에 액세스하려고합니다. 결과적으로 내 반복자가 올바르지 않으며 결과가 정의되지 않은 디버그 어설 션 오류가 발생합니다.
이 문제를 해결할 방법이 있습니까? 난 다른 컴파일 단위의 어떤 주문 개체가 파괴 될지 지정할 수는 없지만 refed_list
이 유효한지 확인하는 방법이 있습니까? 지금은 refed_list.size() == 0
인지 확인하고 작동하는 것처럼 보이지만이 동작은 정의되지 않았습니다 (제 생각에는?). 나는이 생각하지 않습니다
싱글 톤 수명 문제와 비슷합니다. 나는 Scott Meyers 또는 Andrei Alexandrescu가 3 가지 또는 다른 방식으로 그들을 관리하는 것에 관해 썼다고 생각한다. 피닉스 싱글 톤이 당신의 골목을 넘을 수도 있습니다. –
그리고 이것이 내 팀에서 전역 클래스 인스턴스를 허용하지 않는 많은 이유 중 하나입니다. 프로그램 종료 중 오브젝트 파기의 순서는 비 결정적이거나 올바르게되기가 어렵 기 때문에. 어쨌든 WinMain/main 반환 전에 응용 프로그램 정리 기능을 실행할 수 있습니까?아니면 더 나은 아직, 그 소멸자가 뭔가 중요한 임무를 수행하지 않는 한, 왜 모든 개체가 응용 프로그램 종료시 유출하지 않겠습니까? – selbie
@selbie 좋은 생각이라고 생각하기 시작했습니다. 내가 이것을하고있는 이유는 사용되기 전에 무효화 될 수있는 객체를 저장해야하기 때문에'shared_ptr'을 사용할 수 없기 때문에 객체가 유효한지 여부를 알려주는 것이 필요합니다. 따라서 개체를 추적해야하므로 정적 목록이 있습니다. 하지만 그래, 내가 몇 가지를 다시 작성하면 수동으로 닫아서 내 문제를 해결할 수있다. 프로세스로 연결하면 때때로 어려운 일이 일어난다. – user1520427