程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 使用動態數組結構的一個好處

使用動態數組結構的一個好處

編輯:關於C語言

作者:朱金燦 

  請注意,這裡我所說的動態數組不是指你自己new 出來的數組,而是指STL 中的std::vector 和MFC 中的CArray 之類的容器。開始以為使用std::vector 不過是免除動態內存之苦。免除自己手動開辟和釋放內存是一方面,實際上在使用的過程中你會逐漸發現使用std::vector 的好處。今天我就發現了一個好處。

 

今天我修改別人寫的一個圖像匹配算法,所謂圖像匹配就是找出兩幅圖像中相同的地方,在我這個算法中就是找出匹配結果點。別人的代碼大致是這樣的:

 


view plaincopy to clipboardprint?
/*! 
 rief 匹配點信息結構體 
     
*/ 
struct PointInfo   
{  
    long x;  
    long y;  
    long Geo_x;  
    long Geo_y;  
    PointInfo()  
    {  
        x= 0;  
        y=0;  
        Geo_x = 0;  
        Geo_y = 0;  
    }  
};  
/*! 
rief 匹配兩幅圖像,返回匹配結果點數組 
param pLeftImg  左圖像文件句柄 
param pRightImg 右圖像文將句柄 
param lVaildNum 返回的匹配結果點個數 
eturn 匹配結果點數組 
*/ 
PointInfo* ImageMatch(FILE* pLeftImg,FILE* pRightImg,long &lVaildNum)  
{  
      
     long Imgwidth = 0;  
     long ImgHeight= 0;  
     // 獲取左圖像寬高,具體代碼不寫  
      
     // 開辟一個整幅圖像大小的數組  
     PointInfo* pResultPt  = new  PointInfo[Imgwidth*ImgHeight];  
   
     // 開始圖像匹配,具體代碼不寫  
       
     return pResultPt;  

/*!
 rief 匹配點信息結構體
   
*/
struct PointInfo
{
 long x;
 long y;
 long Geo_x;
 long Geo_y;
 PointInfo()
 {
  x= 0;
  y=0;
        Geo_x = 0;
        Geo_y = 0;
 }
};
/*!
rief 匹配兩幅圖像,返回匹配結果點數組
param pLeftImg  左圖像文件句柄
param pRightImg 右圖像文將句柄
param lVaildNum 返回的匹配結果點個數
eturn 匹配結果點數組
*/
PointInfo* ImageMatch(FILE* pLeftImg,FILE* pRightImg,long &lVaildNum)
{
   
  long Imgwidth = 0;
  long ImgHeight= 0;
  // 獲取左圖像寬高,具體代碼不寫
   
     // 開辟一個整幅圖像大小的數組
  PointInfo* pResultPt  = new  PointInfo[Imgwidth*ImgHeight];
 
  // 開始圖像匹配,具體代碼不寫
    
  return pResultPt;
}
 

 

 

    說實話我不喜歡這種函數的設計,為什麼呢?因為我覺得為了很好地避免內存洩露的話,最好遵循這樣一個原則:函數外部申請的內存函數外部釋放,函數內部申請的內存在函數內存釋放,如果像上面的函數設計,用戶往往會忘記釋放 pResultPt 的內存,而且這種釋放也令人感覺不自然。開始我想這樣改為這樣設計:

 


view plaincopy to clipboardprint?
/*! 
rief 匹配兩幅圖像,返回匹配結果點數組 
param pLeftImg  左圖像文件句柄 
param pRightImg 右圖像文件句柄 
param pResultPt 輸入的匹配點數組 
param InitPtNum 輸入的匹配點數組的個數 
param lVaildNum 返回的匹配結果點個數 
eturn 無 
*/ 
void ImageMatch(FILE* pLeftImg,FILE* pRightImg,PointInfo* pResultPt,long InitPtNum,long &lVaildNum)  
{  
     // 具體實現代碼省去  

/*!
rief 匹配兩幅圖像,返回匹配結果點數組
param pLeftImg  左圖像文件句柄
param pRightImg 右圖像文件句柄
param pResultPt 輸入的匹配點數組
param InitPtNum 輸入的匹配點數組的個數
param lVaildNum 返回的匹配結果點個數
eturn 無
*/
void ImageMatch(FILE* pLeftImg,FILE* pRightImg,PointInfo* pResultPt,long InitPtNum,long &lVaildNum)
{
     // 具體實現代碼省去
}
 

 

 

調用這個函數的部分代碼:

 


view plaincopy to clipboardprint?
// 調用代碼  
// 打開左右圖像  
FILE* pLeftImg;  
FILE* pRightImg;  
long Imgwidth = 0;  
long ImgHeight= 0;  
// 獲取左圖像寬高,具體代碼不寫  
long InitPtNum = Imgwidth*ImgHeight;  
PointInfo* pResultPt  = new  PointInfo[InitPtNum];  
long lVaildNum = 0;  
ImageMatch(pLeftImg,pRightImg,pResultPt,InitPtNum,lVaildNum); 
// 調用代碼
// 打開左右圖像
FILE* pLeftImg;
FILE* pRightImg;
long Imgwidth = 0;
long ImgHeight= 0;
// 獲取左圖像寬高,具體代碼不寫
long InitPtNum = Imgwidth*ImgHeight;
PointInfo* pResultPt  = new  PointInfo[InitPtNum];
long lVaildNum = 0;
ImageMatch(pLeftImg,pRightImg,pResultPt,InitPtNum,lVaildNum);
 

 

 

     上面的代碼符合了函數外部申請的內存函數外部釋放,函數內部申請的內存在函數內存釋放的原則,但是依然給人別扭的感覺,首先是要找匹配點,先得開一個整幅圖的大數組(滿足找匹配點的需要,擔心不夠用),然而匹配點往往只占圖像的一小部分;其次是輸入的函數的參數增多了,除了輸入匹配點數組指針,還得輸入數組的難度,輸入參數增多往往增加了用戶的使用難度,比如用戶可能會搞不清楚 long InitPtNum 這個參數所代表的意義 。

 

最後我想比較理想的設計是什麼呢?用戶只需要輸入兩幅圖像的文件句柄和動態數組,調用後返回這個數組就行。於是我想到了下面這個設計:

 


view plaincopy to clipboardprint?
/*! 
rief 匹配兩幅圖像 
param pLeftImg  左圖像文件句柄 
param pRightImg 右圖像文件句柄 
param  VecPt 輸入和匹配點數組 
eturn 無 
*/ 
void ImageMatch(FILE* pLeftImg,FILE* pRightImg,std::vector<PointInfo> &VecPt)  
{  

/*!
rief 匹配兩幅圖像
param pLeftImg  左圖像文件句柄
param pRightImg 右圖像文件句柄
param  VecPt 輸入和匹配點數組
eturn 無
*/
void ImageMatch(FILE* pLeftImg,FILE* pRightImg,std::vector<PointInfo> &VecPt)
{
}
 

這樣設計,首先免去開辟和釋放內存之累,其次你再也不用開辟一大塊內存去應對一個不確定的情況,三是別人使用起來非常自然。

 

   由此看來,適當使用現成的動態數組結構可以使我們的設計更為合理。

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