2011-07-01 119 views
5

在過去的幾天中,調試了一個多線程,其中一個線程正在刪除一個仍在被另一個線程使用的對象,我意識到如果我能夠使這個變量變得更易於診斷,問題會變得更加容易和快速。它會將系統(Symbian OS)上的崩潰轉儲更改爲更多的信息。爲什麼'這'不易變?

那麼,有什麼理由不能或不應該這樣嗎?

編輯: 所以真的沒有安全的方法來防止或檢查這種情況。如果說一個訪問過時類指針的解決方案是擁有一個包含指針的全局變量,並且所調用的任何函數都應該是使用全局變量作爲「this」的替換的靜態,那麼是否正確?

static TAny* gGlobalPointer = NULL; 

#define Harness static_cast<CSomeClass*>(gGlobalPointer); 

class CSomeClass : public CBase 
    { 
public: 
    static void DoSomething(); 

private: 
    int iMember; 
    }; 


void CSomeClass::DoSomething() 
    { 
    if (!Harness) 
     { 
     return; 
     } 

    Harness->iMember = 0; 
    } 

因此,如果另一個線程刪除和NULL全局指針,它會立即被捕獲。

我認爲這樣做的一個問題是,如果編譯器緩存Harness的值,而不是每次使用時檢查它。

+0

你的意思是說,如果this是易失性的,它會更容易,或者如果this是一個指向volatile的指針,它會更容易?換句話說,你是否在崩潰轉儲中看到'this'的過期值(這看起來有點奇怪,因爲它從不改變),或者某些數據成員? –

回答

7

是不變量,但是恆定的。您可以更改參考的對象,但不能更改此值。因爲常數永遠不會改變,所以不需要將它們標記爲不穩定。

+1

而「常量」是指'T * const'而不是'const T *'。 –

+2

用C++術語來說,答案並不合理。這是一個表達。 ''const'表達式當然可以在C++中改變:'int x = 0; int const * px =&x; std :: cout << * px; x = 1; std :: cout << * px;'。 – MSalters

+0

@Mike不,他不是指'T * const'他是指一個不是對象的'T *'。做這個'''const'也是沒有意義的。那麼,至少我假設他的意思。否則他的回答對我來說沒有意義! –

2

它可以。只需將成員函數聲明爲volatile即可。

struct a 
{ 
    void foo() volatile {} 
}; 
+1

爲了回答實際問題,默認情況下不會發生這種情況的原因是,您無法將'this'傳遞給採用指向非易失性指針的函數。相同的原因'this'不是一個指向const的指針,除非你標記成員函數'const'。 –

2

波動不會幫助你。
這將使訪問一個變量易變,但不會等待任何方法來完成。

使用智能指針。

shared_ptr

還有性病在新的C++版本的版本。

+0

Symbian C++中沒有智能指針。我不希望它提供同步,我希望它訪問一個陳舊的指針時崩潰。 – James

+0

@James:不幸的是,使其變得不穩定無法實現。 –

+0

共享指針是受限制的類..您可以將其下載並添加到您的項目 –

4

它不會幫助:製作一個變量易失性意味着編譯器會確保它在每次訪問時都從內存中讀取它的值,但是this的值不會更改,即使從不同的上下文或同樣,你刪除它指向的對象。

+2

...因爲刪除一個指針(特別是指向的內存)不會奇蹟般地將指針設置爲「0」。編譯器無法知道所有指向對象的指針。 –

+0

如果我可以接受多個答案,我會的。謝謝 – James

0

如果在刪除對象時被讀取,這是一個明顯的內存錯誤,並且與volatile無關。

volatile旨在阻止編譯器「記住」內存中可能被不同線程更改的變量值,即阻止編譯器進行優化。

例如如果你的類有一個指針構件p和你的方法正在訪問:

p->a; 
p->b; 

等,p爲內「這個」,因此p->b可以訪問一個不同的對象比它是當它沒有p->a

揮發性如果p已經被銷燬,但是「this」已被刪除,那麼volatile將不會幫助您解救。想必你會認爲它會「無效」,但它不會。

順便說一句,如果你的析構函數爲了保護另一個使用同一個對象的線程而鎖定一個互斥量,這也是一個很好的規則,你有一個問題。您的析構函數可能會因爲它從需要同步活動的外部對象中移除它自己的存在而被鎖定,但不會保護它自己的成員。