basic_string記憶體洩露問題之分析解決
阿新 • • 發佈:2018-12-22
最近在工作中,寫一計算杆塔絕緣子中心點的GPS座標程式時,定義了一結構,裡面用到了string型別來儲存杆塔所屬線路號、杆塔號,杆塔模型名稱。程式碼如下:
1/* 2 @brief 杆塔資訊結構
3*/ 4typedef struct _TOWER_INFO
5{
6 string strLineNo; ///< 線路號
7 string strTowerNo; ///< 杆塔號
8 string strTowerType; ///< 杆塔型別
9 double dDangDistance; ///< 檔距
10 double dHCHeight; ///< 呼稱高
11 double dLongitude; ///< 經度
12 double dLatitude; ///< 緯度
13 double dAltitude; ///< 海拔高度
14 double dLineCorners; ///< 線路轉角
15 long lCornerDirection; ///< 左轉還是右轉: 0不轉, 1左轉, 2右轉
16 vector <INSULATOR_INFO::CENTER_POINT_INFO> vecInsulatorCenterPointInfo; ///< 杆塔所有絕緣子中心點資訊
17 _TOWER_INFO() { memset(this, 0, sizeof(_TOWER_INFO)); } //該行程式碼可能會引起string記憶體洩露18
19}TOWER_INFO,*PTOWER_INFO; 在後面對該結構的string型變數有賦值操作, 程式碼如下
1 ......
2 TOWER_INFO cur_tower_center_info;
3 cur_tower_center_info.strLineNo = sheetLine->Cell(i, 2)->GetText(); //排程碼4 cur_tower_center_info.strTowerNo = sheetLine->Cell(i, 7)->GetText(); //杆塔號5 cur_tower_center_info.strTowerType = sheetLine->Cell(i, 8)->GetText(); //杆塔型別
6 ...... 執行程式,待程式結束後,發現有記憶體洩露,提示資訊如下
1Detected memory leaks! 2Dumping objects -> 3{235250} normal block at 0x01774A60, 16 bytes long.
4 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
5{235237} normal block at 0x01774CB0, 16 bytes long.
6 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
7{235234} normal block at 0x01774A10, 16 bytes long.
8 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
9{235184} normal block at 0x01774200, 16 bytes long.
10 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
11{235171} normal block at 0x01774450, 16 bytes long.
12 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
13{235168} normal block at 0x017741B0, 16 bytes long.
14 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
15{235118} normal block at 0x017739A0, 16 bytes long.
16 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
17{235105} normal block at 0x01773BF0, 16 bytes long.
18 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
19.. 經過一番原始碼跟蹤除錯後,發現原因在於TOWER_INFO結構體的建構函式內呼叫了memset(this, 0, sizeof(_TOWER_INFO);使得string內部指標_Bx._Ptrr值為0,_Myres為0,在這種情況下當string物件被賦值為小字串(位元組數包括結束符小於等於16的字串)時,因新申請的記憶體在後來得不到釋放,所以這塊記憶體被洩露了,根據string類記憶體管理演算法(ms vc版本)得知這塊記憶體大小總是16個位元組.但當被賦值為大字串(位元組數包括結束符大於16的字串)時,反而沒有記憶體洩露,這是因為新申請的記憶體在析構或下次賦值時總能被釋放.
從該洩露問題的分析解決過程中,總結得到規律:不要輕易零初始化string, vector等stl標準容器及具有動態記憶體管理的類。 posted on 2009-08-07 01:31 春秋十二月 閱讀(5541) 評論(19) 編輯 收藏 引用 所屬分類: C/C++
3*/ 4typedef struct _TOWER_INFO
5{
6 string strLineNo; ///< 線路號
7 string strTowerNo; ///< 杆塔號
8 string strTowerType; ///< 杆塔型別
9 double dDangDistance; ///< 檔距
10 double dHCHeight; ///< 呼稱高
11 double dLongitude; ///< 經度
12 double dLatitude; ///< 緯度
13 double dAltitude; ///< 海拔高度
14 double dLineCorners; ///< 線路轉角
15 long lCornerDirection; ///< 左轉還是右轉: 0不轉, 1左轉, 2右轉
16 vector
17 _TOWER_INFO() { memset(this, 0, sizeof(_TOWER_INFO)); } //該行程式碼可能會引起string記憶體洩露18
19}TOWER_INFO,*PTOWER_INFO; 在後面對該結構的string型變數有賦值操作, 程式碼如下
1 ......
2 TOWER_INFO cur_tower_center_info;
3 cur_tower_center_info.strLineNo
6 ...... 執行程式,待程式結束後,發現有記憶體洩露,提示資訊如下
1Detected memory leaks! 2Dumping objects -> 3{235250} normal block at 0x01774A60, 16 bytes long.
4 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
5{235237} normal block at 0x01774CB0, 16 bytes long.
6 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
7{235234} normal block at 0x01774A10, 16 bytes long.
8 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
9{235184} normal block at 0x01774200, 16 bytes long.
10 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
11{235171} normal block at 0x01774450, 16 bytes long.
12 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
13{235168} normal block at 0x017741B0, 16 bytes long.
14 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
15{235118} normal block at 0x017739A0, 16 bytes long.
16 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
17{235105} normal block at 0x01773BF0, 16 bytes long.
18 Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
19.. 經過一番原始碼跟蹤除錯後,發現原因在於TOWER_INFO結構體的建構函式內呼叫了memset(this, 0, sizeof(_TOWER_INFO);使得string內部指標_Bx._Ptrr值為0,_Myres為0,在這種情況下當string物件被賦值為小字串(位元組數包括結束符小於等於16的字串)時,因新申請的記憶體在後來得不到釋放,所以這塊記憶體被洩露了,根據string類記憶體管理演算法(ms vc版本)得知這塊記憶體大小總是16個位元組.但當被賦值為大字串(位元組數包括結束符大於16的字串)時,反而沒有記憶體洩露,這是因為新申請的記憶體在析構或下次賦值時總能被釋放.
從該洩露問題的分析解決過程中,總結得到規律:不要輕易零初始化string, vector等stl標準容器及具有動態記憶體管理的類。 posted on 2009-08-07 01:31 春秋十二月 閱讀(5541) 評論(19) 編輯 收藏 引用 所屬分類: C/C++