2011-04-28 59 views
1

請幫幫忙,靜態變量釋放爲了

的問題:在下面的代碼核心轉儲:

我有一個抽象類SomeOtherClass,並從中衍生SomeOtherClassImpl。

這是導致麻煩的代碼:我有MyClass的類型的一些靜態變量在其他翻譯單元

class MyClass 
{ 

public: 

    void someFunction() 
    { 
    myVector().push_back(someOtherClassDefault()); 
    } 

private: 

    static std::vector<SomeOtherClass const *> & myVector() 
    { 
    static std::vector<SomeOtherClass const *> theVector; 
    return theVector; 
    } 

    static SomeOtherClass const * someOtherClassDefault() 
    { 
    static SomeOtherClassImpl theDefault; 
    return &theDefault; 
    } 

}; 

該問題很奇怪,因爲程序退出時發生段錯誤。當然可以在矢量之前釋放默認值,但有什麼區別?當main已經完成時,兩者都釋放。

您的幫助將不勝感激。

+3

上面的代碼我看不出任何明顯的錯誤,所以你可能需要提供一個「SomeOtherClassImpl」的精簡版本。如果您在調試器中運行應用程序,發生seg-fault時的回溯是什麼? – 2011-04-28 16:27:51

+1

你認爲「main已經完成」之後會發生什麼事情與你無關? – 2011-04-28 16:35:26

+0

尼古拉,謝謝你激勵評論:)但你是對的,這是我的事,而這實際上是我的錯誤。 – 2011-04-29 13:43:51

回答

4

你最有可能在相反的一端觸及靜態初始化失敗。基本上,靜態持續時間的對象的破壞順序與創建對象的順序相反。所以,如果您有:

void foo() { 
    static type a; 
} 
void bar() { 
    static type b; 
} 
int main() { 
    foo(); 
    bar(); 
} 

建設將創造第一a,然後bmain完成時,它會破壞b然後a。如果您在main中切換呼叫的順序,則順序將被反轉。出於這個特殊原因,在處理依賴關係的靜態持續時間變量時必須注意。

+1

沒錯,但是你能在OP的代碼中看到爲什麼順序很重要嗎?我不能。 – 2011-04-28 16:43:38

+0

我不能。可能有一些其他代碼在被銷燬後訪問這些對象中的一個。 – hammar 2011-04-28 17:45:15

+0

我在代碼中看不到它,但從描述來看,這似乎是問題所在。很可能這是一個簡化版本,其中的矢量替換了一些實際訪問破壞參數的其他類。說一個包含向量的類,並且在銷燬時遍歷元素並調用成員函數。在這種情況下,該類將在元素之前創建,並且在該類的銷燬期間,迭代會觸及被破壞的對象。 – 2011-04-28 18:47:34