Chinaunix首页 | 论坛 | 博客
  • 博客访问: 263427
  • 博文数量: 28
  • 博客积分: 688
  • 博客等级: 上士
  • 技术积分: 365
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-16 10:25
文章分类

全部博文(28)

文章存档

2012年(28)

我的朋友

分类: WINDOWS

2012-04-09 09:19:19

上文介绍了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 #include   // 内存泄漏追踪类 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 #include   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号找到泄露内存代码的具体位置,添加释放代码。

阅读(3428) | 评论(0) | 转发(0) |
0

上一篇:isodata程序

下一篇:opencv的assert函数

给主人留下些什么吧!~~