有效解決內存洩露
一、你需要一個函數將一個數組賦值為等差數列,並將會在函數的外部使用它。
不合理:
int *GetArray( int n )
{
int *p = new int[n];
for ( int i = 0; i < n; i++ )
{
p[i] = i;
}
return p;
}
合理:
void GetArray( int *p, int n )
{
for ( int i = 0; i < n; i++ )
{
p[i] = i;
}
}
解析:
檢查內存洩露的最好辦法,就是檢查完全配對的申請和釋放,在函數中申請而在外部釋放,將導致代碼的一致性變差,難以維護。
而且,你寫的函數不一定是你自己使用的,這樣的函數別人會不知道該怎麼適當的使用,如果它是一個DLL的導出函數,並且你在不同的平台下使用了,便會導致系統崩潰。最好的解決辦法就是在函數調用的外面將內存申請好,函數只對數據進行復制。
二、你需要寫一個類來為你管理一個指針,這個類將封裝對指針的申請內存、釋放和其它一些基本操作。
不合理:
class A
{
public:
A( void ) {}
~A( void ) { delete []m_pPtr; }
void Create( int n ){ m_pPtr = new int[n]; }
private:
int *m_pPtr;
};
合理:
class A
{
public:
A( void ) : m_pPtr(0){}
~A( void ) { Clear(); }
bool Create( int n ){ if ( m_pPtr ) return false; m_pPtr = new int[n]; return ture; }
void Clear( void ) { delete []m_pPtr; m_pPtr = 0; }
private:
int *m_pPtr;
};
解析:
不合理的代碼就在於當你重復調用Create的時候就會造成內存洩露,解決的辦法就是在new之前判斷一下指針是否為0。要能夠有效的執行這個判斷,則必須在構造的時候對指針進行初始化,並為這個類添加一個Clear函數來釋放內存。
三、接上題的Create函數,你現在需要根據傳入的參數做一些比較復雜的算法操作,並對申請的數組賦值。
不合理:
bool Create(int *a, int n )
{
if ( m_pPtr )
return false;
m_pPtr = new int[n];
for ( int i = 0; i < n; i++ )
{
m_pPtr[i] = 3 / a[i];
}
return true;
}
合理:
template<class _Ty>
class auto_array
{
public:
explicit auto_array(_Ty *pPtr=0)throw():m_Ptr(pPtr){}
~auto_array(){delete[]m_Ptr;}
void reset(_Ty *pPtr=0){if(pPtr!=m_Ptr){delete[]m_Ptr;m_Ptr=pPtr;}}
_Ty* release(void){_Ty *pTemp=m_Ptr;m_Ptr=0;return pTemp;}
private:
auto_array(const auto_array&other){}
auto_array& operator=(const auto_array& other){}
_Ty *m_Ptr;
};
bool A::Create(int *a, int n )
{
if ( m_pPtr )
return false;
auto_array<int> PtrGuard( new int[n] );
for ( int i = 0; i < n; i++ )
{
if ( 0 == a[i] )
{
return false;
}
PtrGuard .get()[i] = 3 / a[i];
}
m_pPtr = PtrGuard.release();
return true;
}
解析:
在循環中,當參數數組a中的某一個值為0時,將會產生除0異常,那麼,這將會導致你在上面為m_pPtr申請的內存不能合理的釋放。為了解決這個問題,我們寫了一個auto_array作為衛兵來看守企圖逃逸的指針。
在auto_array對象PtrGuard析構的時候它會同時刪除附加在它身上的內存指針。我們首先用PtrGuard來進行所有的指針操作,在確定操作完全結束的最後,把指針再賦給真正的變量,並使PtrGuard放棄對該指針的附加,這樣我們就得到了一個最安全的結果。
另外需要注意的是,C++的STL庫裡本來有一個和auto_array功能非常相似的模版類auto_ptr,但是它只支持單個對象的內存,不支持數組,寫這樣一個auto_array也是不得已而為之。