簡體   English   中英

Visual C ++運行時對象銷毀順序

[英]Visual C++ runtime object destruction order

我偶然發現了一個相當討厭的問題,當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自身添加到refed_list ,並在其析構函數中刪除自身。 如果封裝狀態被關閉,則通知MyClass並檢查封裝實例的refed_list並使其指針無效。 這並不重要,重要的是它使用static list並在構造函數/析構函數中訪問此列表。 我在定義MyClass的文件中初始化refed_list

現在,問題..當我的程序關閉時,運行時refed_list在某個時刻清除refed_list ,然后清理MyClass的實例,調用它們的析構函數。 然后他們嘗試訪問已經清理過的refed_list 這導致我的迭代器不正確,並且我得到未定義的行為,在這種情況下調試斷言失敗。

有沒有解決這個問題的方法? 我懷疑我可以指定不同編譯單元中的哪些訂單對象被破壞,但有沒有辦法檢查refed_list是否仍然有效? 目前我檢查是否refed_list.size() == 0它似乎工作,但這種行為也是未定義的(我認為?)。

您始終可以使refed_list成為啟動時初始化的指針。 這樣它永遠不會被清理干凈。 (當進程退出時,操作系統將恢復它使用的任何內存。)

如果這聽起來像是一個解決更深層設計問題的黑客,那么它可能就是這樣。 :)

我不認為這是真的:

當我的程序關閉時,運行時會在某個時刻清除refed_list,然后清理MyClass的實例,調用它們的析構函數。

運行時肯定會清理列表,但不會清除列表中的對象,因為它們是指針。 唯一的方法是使用像shared_ptr這樣的智能指針類。 盡管如此,如果你這樣做,對象會在它被銷毀時嘗試訪問列表,我不確定它是不確定的行為,但它肯定是不穩定的。

也許您應該重新設計它,以便對象不需要引用它們存儲的列表,或者至少在列表被銷毀之前執行它(並且我的意思是在list :: ~list甚至被調用之前) 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM