最近在工作中,寫一計算桿塔絕緣子中心點的GPS坐標程序時,定義了一結構,里面用到了string類型來存儲桿塔所屬線路號、桿塔號,桿塔模型名稱。代碼如下:
1
/*
2
@brief 桿塔信息結構
3
*/
4
typedef 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 ...... 運行程序,待程序結束后,發現有內存泄露,提示信息如下
1
Detected memory leaks!
2
Dumping 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
春秋十二月 閱讀(7732)
評論(19) 編輯 收藏 引用 所屬分類:
C/C++