關於構造函數析構函數以及成員變量內存分配順序的一些問題

昨天發了版本,今天稍微有點空,記錄點東西。


大約兩三個月前,我追查我們遊戲在弱網情況下遇到的一個啓動卡住的問題,與同事一起打日誌,追到一個類的構造方法時,發現構造方法裏的日誌打印不出來。我們最初懷疑是不是代碼哪裏出了問題導致內存爆掉從而使得這個對象的內存分配失敗,但通過工具發現並沒有出現突然間內存爆漲的情況。沒辦法,只好重載這個類的new方法並在其中加上日誌,看是在哪一步導致這個類的構造函數沒有被執行。

當時這個類大約長這個樣子:


class A

{

public:

...

public:

somfunction

......

PROP(ClassB, objB);

......

......

somefunciton

private:

bool m_var1;

int m_var2;

};


這個類的頭文件大約100來行,初看了一下最底下的數據聲明,純粹的兩個字段,重載其new方法後,我們打印其size發現竟然有80多字節。驚不驚喜?於是細看代碼,發現了夾在中間的一個屬性定義:PROP(ClassB, objB)。一堆方法之中夾了一個屬性定義。那麼方向就很明確了。肯定是在這個屬性定義中,給這個字段 objB 分配內存時失敗了,因爲成員的內存分配是先於對象的構造函數執行的。

於是我們追進去細看其中代碼,發現在這個ClassB的構造方法中,調用了一個方法:getHostByName!這個方法是個線程阻塞的,如果在網絡好的情況下,這個方法返回是很快的,但是在弱網下(或者說局域網可用而互聯網不可用的時候)這個方法是會一直阻塞在那裏的,導致 objB 的構造函數一直阻塞着進一步導致 class A 的構造函數沒辦法執行。


這裏再次記錄一下大學裏老師講過的,但不會結合具體場景給學生講的一個知識點:

構造方法執行順序:父類->成員變量->自己

析構方法執行順序:自己->成員變量->父類


這個不起眼的知識點,在關鍵時刻會幫上大忙。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章