OpenCV内存泄露的检测

来源:互联网 发布:项目经理懂代码 知乎 编辑:程序博客网 时间:2024/05/21 10:03

OpenCV内存泄露的检测

上文介绍了C/C++编码中内存泄露的问题,不过经过本人测试,好像对用opencv工具包进行编码中的内存泄露并不起作用。CrtSetDbgFlag函数应该针对new/malloc这种方式分配内存的,而opencv的很多函数把内存分配封装了,直接返回一个指针(e.g. cvCreateImage返回IplImage指针),因而并不能检测出opencv编码的内存泄露.(这一段不知道说得对不对,还有待查证:0) ).针对这个问题,网上有一个比较好的解决方法,就直接来过来用了。它是一个针对opencv的内存泄露检测的类,实现如下:

  
//头文件#ifndef OPENCV_MEM_TRACKER_H#define OPENCV_MEM_TRACKER_H #include <stdio.h>#include <vector> // 内存泄漏追踪类class MemTracker{public:   MemTracker(void);   ~MemTracker(void); private:    // 登记分配/释放的内存   void regAlloc(void *ptr, size_t size);   void regFree(void *ptr);    // 输出泄漏的内存   int output(FILE* fp=stderr); private:    // 分配内存   static void* alloc_func(size_t size, void *userdata);    // 释放内存   static int free_func(void *ptr, void *userdata); private:     struct Ptr   {      void *ptr;      // 内存地址      size_t size;   // 内存大小      int   id;       Ptr(void *ptr, size_t size, int id)      {         this->ptr = ptr;         this->size = size;         this->id = id;      }   };    // 记录当前使用中的内存   std::vector<Ptr>   m_memTracker;     // alloc_func对应的编号   int   m_id;}; #endif   // OPENCV_MEM_TRACKER_H  //cpp文件#include "MemTracker.h" #include <assert.h>#include <cv.h> MemTracker::MemTracker(void){m_id = 0;    // 注册管理函数   cvSetMemoryManager(alloc_func, free_func, (void*)this);} MemTracker::~MemTracker(void){   // 取消管理函数    cvSetMemoryManager(NULL, NULL, NULL);    // 输出结果    this->output();} // 登记分配/释放的内存 void MemTracker::regAlloc(void *ptr, size_t size){   // 每次记录一个新的m_id   m_memTracker.push_back(Ptr(ptr, size, m_id++));} void MemTracker::regFree(void *ptr){   int i;   for(i = 0; i < m_memTracker.size(); ++i)   {      // 删除记录      if(m_memTracker[i].ptr == ptr)      {         m_memTracker[i] = m_memTracker[m_memTracker.size()-1];         m_memTracker.pop_back();         return;      }   }} // 输出泄漏的内存 int MemTracker::output(FILE* fp){int n = m_memTracker.size();   int i;    for(i = 0; i < n; ++i)   {      fprintf(fp, "%d: %p, %u\n", m_memTracker[i].id, m_memTracker[i].ptr, m_memTracker[i].size);   }    return n;} // 分配内存 void* MemTracker::alloc_func(size_t size, void *userdata){   assert(size > 0 && userdata != NULL);    // 分配内存    void *ptr = malloc(size);   if(!ptr) return NULL;    // 登记   MemTracker *tracker = (MemTracker*)userdata;   tracker->regAlloc(ptr, size);    //    return ptr;} // 释放内存 int MemTracker::free_func(void *ptr, void *userdata){   assert(ptr != NULL && userdata != NULL);    // 释放内存    free(ptr);    // 登记    MemTracker *tracker = (MemTracker*)userdata;   tracker->regFree(ptr);    // CV_OK == 0    return 0;}  //测试程序int main(){   //实例化   MemTracker tracker;      //加载图片,注意它没有被release掉   IplImage * pImg = cvLoadImage("E:\\test photos3\\SDC10126.JPG", 1);    return 0;}

 

使用的时候,MemTracker会跟每一个指针分配一个id,并记录它的分配与释放情况,对没有释放的内存将会被打印出来,包括此指针的id号, 指针的16进制值,以及所指内存的大小。按f5进行调试,根据id号找到泄露内存代码的具体位置,添加释放代码。

分类: OpenCV
0 0
原创粉丝点击