又見懸空指標
概念
懸空指標:顧名思義,其指向的記憶體已經被釋放,但是指標使用者並不知道,通過指標訪問了非法記憶體,結果隨機。懸空指標常發生在指標淺拷貝場景,根本原因是資訊不同步問題。
實際場景
最近對引擎做一次比較大升級,結果還是引入了一些隱晦BUG,本文著重還原一個懸空指標的場景。示例程式碼如下:
class StyleMgr {
public:
StyleMgr(): _default(NULL), pStyleArr(NULL) { /* .. 其他初始化 ..*/ }
//... 析構 ...
int Create(const char* file, int index) {
Clear();
_pStyleArr = new Style[];
// ... parse from file...
}
void Clear() {
_hashTb.removeAllObject();
delete [] _pStyleArr;
_pStyleArr = NULL;
}
Style* GetStyle(int id) {
if (!_default) {
_default = _hashTb.find(DEFAULT_CODE);
}
if (!_hashTb.has_contains(id)) {
return _default;
}
return _hashTb.find(id);
}
private:
Style* _pStyleArr;
HashTable _hashTb;
Style* _default;
};
StyleMgr內部_pStyleArr是樣式陣列,儲存所有style指標,_hashTb為樣式雜湊表為了快速查詢,_default為查詢失敗的預設樣式。_default, _hashTb都與_pStyleArr共享內部指標。懸空指標出錯的場景:
StyleMgr smgr = new StyleMgr();
// 1.首次建立...
smgr.Create("style.dat", 0);
// 2.獲取樣式...
style1 = smgr.GetStyle(id1);
style2 = smgr.GetStyle(id2);
// 3.其他地方再次建立
smgr.Create("style.dat", 1);
// 4.懸空指標出場:
style3 = smgr.GetStyle(bad_ID);
注意:上面4段程式碼都不在一個地方。
第二段程式碼呼叫GetStyle以後此時_default指向了首次Create時_pStyleArr內部的同時也是_hashTb內部的一個樣式。
第三段程式碼再次呼叫Create函式,此時Create內部呼叫Clear以後,重建了_pStyleArr和_hashTb結構,此時_default仍然不為空,持有已經釋放的記憶體地址。
第四段程式碼再次呼叫GetStyle時候,如果傳入的是合法ID,結果OK!但是當傳入非法ID,將_default返回,結果就隨機了。。。
原因分析:coding的時候沒意識到Create函式會多次重入,Clear函式本意是將整個StyleMgr成員狀態重置,忘記處理_default。於是當Create、GetStyle、Create、GetStyle組合呼叫時,最後一次的GetStyle引入了懸空指標隱患,多次重入取到的預設樣式可能隨機。
後話
巨大的一個工程中,而且涉及不同地方呼叫,指望CV很難發現問題。通過gflags也沒發現問題,因為只有查詢失敗時才返回default樣式,而且返回後還不一定出錯。
這個BUG是程式碼提交十天後才發現,當時跟蹤另外一個bug,除錯的時候偶然發現_default指向內容為空。。。然後就查啊查啊查。。。
查到問題改起來十分容易啦~
指標問題沒有小問題,對待指標問題一定小心又小心。。。
- 20140405 dizuo
相關文章
- 指標-又見迴文指標
- 懸掛指標指標
- 野指標 空指標指標
- 防止空指標指標
- c++指標使用經驗總結之懸垂指標C++指標
- GO 空指標和nilGo指標
- 如何避免空指標出錯?指標
- 8.空指標異常指標
- 滑鼠懸浮元素指標十字架指標
- NullPointerException空指標異常的理解NullException指標
- 常見指標型別入門指標型別
- Java中如何避免空指標異常Java指標
- 常見網際網路分析指標指標
- 軟體效能測試常見指標指標
- C語言指標常見問題C語言指標
- C++ 指標常見用法小結C++指標
- Java中如何處理空指標異常Java指標
- 使用Java 8 Optional避免空指標異常Java指標
- 空指標漏洞防護技術(提高篇)指標
- NULL 指標、零指標、野指標Null指標
- 滑鼠懸浮出現十字架形滑鼠指標指標
- 指標常見問題(Android之JNI)指標Android
- 關於sizeof,對空指標sizeof(*p)可以嗎?指標
- Java8的Optional:如何幹掉空指標?Java指標
- Kafka SimpleStringSchema 可能會造成空指標異常Kafka指標
- java.lang.NullPointerException 空指標異常問題JavaNullException指標
- java 空指標異常造成的原因有哪些Java指標
- 空指標漏洞防護技術(初級篇)指標
- 通達信速度空間指標公式原始碼指標公式原始碼
- mybatis lambdaQuery 查詢條件導致空指標MyBatis指標
- C語言知識彙總 | 56-C語言NULL空指標以及void指標C語言Null指標
- AI 模型常見的評價指標彙總AI模型指標
- 常見演算法技巧之——雙指標思想演算法指標
- [轉載] java避免空指標異常_第1部分:在現代Java應用程式中避免空指標異常Java指標
- 程式的虛擬地址空間——NULL指標分割槽Null指標
- getter,setter 直接修改造成的空指標異常指標
- 指標常量和常量指標指標
- 皇御貴金屬:貴金屬指標之多空指標的應用解析指標