2011-11-14 25 views
3

我的存儲器使用下一段代碼,一旦得到充分相當快。 Valgrind顯示內存泄漏,但是一旦函數結束,所有內容都被分配到堆棧上(應該是)釋放。OpenCV的墊創作產生內存泄露

void mult_run_time(int rows, int cols) 
{ 
    Mat matrix(rows,cols,CV_32SC1); 
    Mat row_vec(cols,1,CV_32SC1); 

    /* initialize vector and matrix */ 
    for (int col = 0; col < cols; ++col) 
    { 
     for (int row = 0; row < rows; ++row) 
     { 
      matrix.at<unsigned long>(row,col) = rand() % ULONG_MAX; 
     } 

     row_vec.at<unsigned long>(1,col) = rand() % ULONG_MAX; 
    } 
    /* end initialization of vector and matrix*/ 

    matrix*row_vec; 
} 

int main() 
{ 
    for (int row = 0; row < 20; ++row) 
    { 
     for (int col = 0; col < 20; ++col) 
     { 
      mult_run_time(row,col); 
     } 
    } 

    return 0; 
} 

Valgrind的顯示,是本着Mat row_vec(cols,1,CV_32CS1)內存泄漏:

==9201== 24,320 bytes in 380 blocks are definitely lost in loss record 50 of 50 
==9201== at 0x4026864: malloc (vg_replace_malloc.c:236) 
==9201== by 0x40C0A8B: cv::fastMalloc(unsigned int) (in /usr/local/lib/libopencv_core.so.2.3.1) 
==9201== by 0x41914E3: cv::Mat::create(int, int const*, int) (in /usr/local/lib/libopencv_core.so.2.3.1) 
==9201== by 0x8048BE4: cv::Mat::create(int, int, int) (mat.hpp:368) 
==9201== by 0x8048B2A: cv::Mat::Mat(int, int, int) (mat.hpp:68) 
==9201== by 0x80488B0: mult_run_time(int, int) (mat_by_vec_mult.cpp:26) 
==9201== by 0x80489F5: main (mat_by_vec_mult.cpp:59) 

它是OpenCV中已知的錯誤還是我失去了一些東西?

+2

這可能是無關的,但你肯定'CV_32SC1'是'無符號long'?他們看起來更像'int'我...(我不知道你是否在你沒有真正允許,因爲無符號長是更大的存儲空間寫,在位數,比整數) – Fezvez

+0

Fezvez是正確的,你是實際上是編寫未分配的內存。結果是出乎意料的。 – Sam

+0

將'unsigned long'更改爲'int'和'ULONG_MAX'更改爲'INT_MAX'。內存泄漏仍然存在。 –

回答

1

有長在

matrix.at<unsigned long>(row,col) = rand() % ULONG_MAX; 

在使用無符號沒有使用,因爲蘭特()反正返回一個intenger,所以在總範圍內沒有增益,因此用無符號整型代替。

在行:

row_vec.at<unsigned long>(1,col) = rand() % ULONG_MAX; 

正在訪問的外部範圍索引。在C++中,向量從0開始,而不是從1開始。矩陣在opencv中逐行存儲。您正在訪問未分配的內存區域,這可能是valgrind查找內存泄漏的原因。用途:

row_vec.at<unsigned int>(col, 0) = rand() % ULONG_MAX; 

我相信,你是不是在調試模式下編譯程序,因爲如果那樣的話,OpenCV的使用斷言訪問索引以確保您的矢量的總範圍內之前,如果你在調試模式下編譯,你的程序會在你的代碼執行過程中拋出一個斷言失敗,這樣更容易跟蹤這種錯誤。我建議您在調試模式下開始構建原型代碼。

+0

哦,很酷的thnx ...我想你是對的。我第一次編譯OpenCV時,使用'CMAKE_BUILD_TYPE = RELEASE'。如果我已將標誌更改爲DEBUG並再次重新編譯OpenCV,它是否會與發佈版一起構建調試庫,並允許我定義編譯模式? –

+0

重新編譯代碼而不是使用預先構建的二進制文件([link](http://sourceforge.net/projects/opencvlibrary/files/))的唯一原因是設置使用第三個庫,如EIGEN( [鏈接](http://eigen.tuxfamily.org/))。如果情況並非如此,那麼您可以立即使用預製的二進制文件。他們已經提供了調試庫文件,只是鏈接它們,斷言失敗將被拋出。他們沒有提供調試信息,如果您想在調試過程中使用OpenCV代碼,則需要使用調試標誌重新編譯它。 (好吧,還有另一個原因......) –

0

我同意,部分用@IanMedeiros:這裏正確鑄造unsigned int

但是,真正的交易是類型的墊的有只有一個正確的演員。 關於列表檢查this answer here。 答案給出了正確的灰度圖像強制轉換。

對於多通道圖像您需要投射到Vec<mat_type, num_channels>

從opencv2 lib中最常見的預定義的VEC的:

typedef Vec<uchar, 3> Vec3b; // this is how a color image gets usually loaded 
typedef Vec<short, 3> Vec3s; 
typedef Vec<ushort, 3> Vec3w; 
typedef Vec<int, 3> Vec3i; 
typedef Vec<float, 3> Vec3f; 
typedef Vec<double, 3> Vec3d;