程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 高質量C++編程點滴(一)

高質量C++編程點滴(一)

編輯:C++入門知識

有效解決內存洩露

  一、你需要一個函數將一個數組賦值為等差數列,並將會在函數的外部使用它。

  不合理:

 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也是不得已而為之。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved