当前位置: 首页 > news >正文

学做烘焙的网站/如何接广告赚钱

学做烘焙的网站,如何接广告赚钱,酒业公司网站模板,个人可以做行业网站吗内存泄漏时程序开发中经常遇到的问题. 而且出现内存泄漏很难检测,但是其导致的结果却是灾难性的. 这里讲一下opencv中内存泄漏检测的一些技巧.OpenCV中关于内存管理主要涉及到以下3个函数:CV_IMPL void cvSetMemoryManager( CvAllocFunc alloc_func, CvFreeFunc free_func, vo…

内存泄漏时程序开发中经常遇到的问题. 而且出现内存泄漏很难检测,

但是其导致的结果却是灾难性的. 这里讲一下opencv中内存泄漏检测

的一些技巧.

OpenCV中关于内存管理主要涉及到以下3个函数:

CV_IMPL void  cvSetMemoryManager( CvAllocFunc alloc_func, CvFreeFunc free_func, void* userdata );

CV_IMPL void* cvAlloc( size_t size );

CV_IMPL void  cvFree_( void* ptr );

还有一个对应cvFree_的宏:

#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0)

宏cvFree的用处是在释放ptr指针对应的内存后, 将ptr设置为NULL.

这里我们先做个假设: opencv中所有的内存分配和释放都是通过cvAlloc和cvFree合作完成的.

如果你使用cvAlloc分配一个内存, 然后用delete来是释放内存是错误的(切记)!!!

因此, 如果我们能够跟踪到cvAlloc/cvFree的调用流程, 就可以分析内存泄漏的情况了.

一般情况下, 一个cvAlloc分配的内存最终必然要对应cvFree来释放, 如果cvAlloc/cvFree不是

匹配出现, 那么可以认为出现了内存泄漏.

为此, 我们需要定义自己的内存管理函数, 然后通过cvSetMemoryManager装载到opencv中.

内存管理函数的类型如下:

typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata);

typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata);

其中的userdata是用户通过cvSetMemoryManager来设置的. 我们可以简单的吧userdata当作一个

容器指针, 在每次执行我们自己的alloc_func/free_func函数时, 将内存的分配/释放情况记录到

userdata对应的容器.

为此, 我自己简单设计了一个MemTracker类:

#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;   // 内存大小

Ptr(void *ptr, size_t size)

{

this->ptr = ptr;

this->size = size;

}

};

// 记录当前使用中的内存

std::vector   m_memTracker;

};

#endif   // OPENCV_MEM_TRACKER_H

类的实现如下:

#include "MemTracker.h"

#include

#include

MemTracker::MemTracker(void)

{

// 注册管理函数

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_memTracker.push_back(Ptr(ptr, size));

}

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", i, 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;

}

MemTracker在构造的时候会注册自己的内存管理函数, 在析构的时候会输出没有被释放的内存.

下面我们编写一个测试程序:

#include

#include

#include "MemTracker.h"

int main()

{

MemTracker mem;

IplImage *img = cvLoadImage("lena.jpg", 1);

if(!img) return -1;

// 没有释放img内存

// cvReleaseImage(&img);

return 0;

}

在main函数退出的时候mem会被析构, 然后输出内存的泄漏情况. 下面是在我的电脑上测试的结果:

C:/work/vs2005/MemTracker/debug>MemTracker.exe

0: 00C750C0, 112

1: 00D90040, 786432

OK, 先说到这里吧, 下次再补充...

前面我们已经解决了内存泄漏的检测, 但是在出现内存泄漏的时候我们怎么才能

跟踪到出现内存泄漏的代码呢? 如果能够调试到没有被释放内存对应的cvAlloc函数就好了.

这个我们可以通过m_memTracker[i].ptr来比较内存的地址来检测, 例如在alloc_func中

添加以下代码, 然后设置断点:

// 检测00C750C0内存

if(ptr == (void*)00C750C0)

{

// 设置断点

}

但是这个方法可能还有缺陷. 因为每次运行程序的时候, 内存的布局可能是有区别的.

最好的方法是把cvAlloc的调用顺序记录下来.

变动的部分代码:

class MemTracker

{

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   m_memTracker;

// alloc_func对应的编号

int               m_id;

};

MemTracker::MemTracker(void)

{

m_id = 0;

// 注册管理函数

cvSetMemoryManager(alloc_func, free_func, (void*)this);

}

void MemTracker::regAlloc(void *ptr, size_t size)

{

// 每次记录一个新的m_id

m_memTracker.push_back(Ptr(ptr, size, m_id++));

}

// 输出泄漏的内存

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;

}

以后就可以根据m_memTracker[i].id来设置断点跟踪调试. 因为每次运行程序的时候, cvAlloc的调用次序是不变

的, 因此可以认为每次cvAlloc对应的id也是不变的. 这样就可以根据id来追踪出现内存泄漏的cvAlloc了.

对于"OpenCV扩展库", 可以将MemTracker直接集成到CvxApplication中, 这样就可以默认进行内存泄漏检测了.

内存检测先说到这里, 下一节我会简要分析一下OpenCV的cvAlloc等源代码 :D

前面的帖子中我们已经讨论了cvAlloc/cvFree_/cvSetMemoryManager等函数的使用技巧.

下面开始分析OpenCV中以上函数的实现代码. 我觉得如果在阅读代码之前, 如果能对函数的

用法有个基本的认识, 那么对于分析源代码是很有帮助的.

CV_IMPL  void*  cvAlloc( size_t size )

{

void* ptr = 0;

CV_FUNCNAME( "cvAlloc" );

__BEGIN__;

if( (size_t)size > CV_MAX_ALLOC_SIZE )

CV_ERROR( CV_StsOutOfRange,

"Negative or too large argument of cvAlloc function" );

ptr = p_cvAlloc( size, p_cvAllocUserData );

if( !ptr )

CV_ERROR( CV_StsNoMem, "Out of memory" );

__END__;

return ptr;

}

从代码我们可以直观的看出, cvAlloc分配的内存不得大于CV_MAX_ALLOC_SIZE, 即使是使用我们

自己的内存管理函数也会有这个限制.

然后通过p_cvAlloc对应的函数指针对应的函数来分配内存. p_cvAlloc是一个全局static变量, 对应的

还有p_cvFree和p_cvAllocUserData, 分别对应释放内存函数和用户数据. 它们的定义如下:

// 指向分配函数的指针,初始设置为默认值

static CvAllocFunc p_cvAlloc = icvDefaultAlloc;

static CvFreeFunc p_cvFree = icvDefaultFree;

static void* p_cvAllocUserData = 0;

http://www.lbrq.cn/news/1102861.html

相关文章:

  • 深圳商城网站建设报价/网站建成后应该如何推广
  • 建设网站的发布与推广/seo零基础入门到精通200讲
  • 制作钓鱼网站属于什么罪/seo营销推广服务公司
  • 怎么建设网站网页/快速排名程序
  • 想象力做网站/seo简介
  • wordpress 下载页插件/seo排名优化公司哪家好
  • 葫芦岛市网站建设/河南seo关键词排名优化
  • 做网站投资多少钱/今日热点新闻2022
  • 个人做网站租云服务器/百度保障平台 客服
  • 制作公司网站的步骤/百度网盘资源链接入口
  • 设计联盟网站/免费域名怎么注册
  • 想做设计师需要学什么/长沙seo免费诊断
  • 做关于时尚网站的目的/成都网络推广中联无限
  • 2016网站开发语言/seo网站优化培训价格
  • 六安网站关键词排名优化报价/深圳优化公司样高粱seo
  • 上海哪家公司做网站好/网络营销的市场背景
  • 怎么做考试资料分享网站/seo快速排名是什么
  • 怎样在我的世界做汽车视频网站/免费建网站软件哪个好
  • 网站的竞价怎么做/青岛seo优化公司
  • 网上写作真正能赚钱的网站/友链互换平台推荐
  • 招聘网站上找在家做/百度付费推广
  • 政府门户网站建设取得/快速seo优化
  • 网站建设深/网店运营实训报告
  • 2023免费推广网站/百度下载安装到桌面上
  • 网站建设支付/百度sem认证
  • 深圳电商网站开发公司/镇江百度推广
  • 果洛wap网站建设公司/搜索引擎排名机制
  • 大理微网站建设/网络营销公司哪家好
  • 电商客服外包加盟代理/网站优化公司开始上班了
  • 做网站还要做点手机吗/数据分析师要学什么
  • 【GameMaker】GML v3 的现行提案
  • 2025.7.20总结-实战演讲
  • 【数据结构】二维差分数组
  • 线程池的状态
  • 手撕Spring底层系列之:注解驱动的魔力与实现内幕
  • KVM中使用桥接模式.运维就业技术教程