大家来看看,我自己封装的opencv的求矩阵正弦的函数,调用前究竟要不要申请内存?

天蚕变 发布于 2012/06/23 22:17
阅读 1K+
收藏 1
我自己封装的对矩阵的每个元素求三角sin的函数,如下:
CvMat* cvSinMat(CvMat *a)
{
int rows = a->rows;
int cols = a->cols;
CvMat *out = cvCreateMat(rows, cols, a->type);
for(int i=0; i<rows; i++)
{
float* ptra = ( float*)(a->data.ptr+i*a->step);
float* ptrout = ( float*)(out->data.ptr+i*out->step);
for(int j=0; j<cols; j++)
{
*ptrout = sin(*ptra);
ptra++;
ptrout++;
}
}
return out;
}
我调用的时候,假设inMat是已经有数值的矩阵,我在调用这个函数前是
CvMat *outMat=0;
outMat = sinMat(inMat);
还是:
CvMat *outMat = cvCreateMat(inMat->rows, inMat->cols, inMat->type);
outMat = sinMat(inMat);
究竟用哪一种方式才能避免内存泄露??????????谢谢大家了先 请高人指点
加载中
0
骠骑将军
骠骑将军
在子函数内分配内存(cvCreateMat)不大好吧,
你把函数定义修改为void sinMat(CvMat *in, CvMat *out)这种,在使用的时候
先CvMat *outMat = cvCreateMat(inMat->rows,inMat->cols,inMat->type);
然后sinMat(inMat,outMat)
用完了释放内存cvReleaseMat(&outMat)
天蚕变
天蚕变
恩好的。 我就是发现我的程序内存泄露太严重了
1
中山野鬼
中山野鬼

openCV又有C,又有C++,所以比较混乱。另外,04年前后看过一些OPENCV的源码,结果发现太弱了,所以没怎么研究过。楼主我不知道你是用C还是用C++折腾。我这里只是基于C的思想给出我的一些观点。关于你上面的代码。

1、如果我没理解错,你的a->step,实际是a->data.ptr的数据存储的位宽。一般你应该这样写:

u32 step = a->step;
u32 stride = rows * step;
float *f = a->data.ptr;
float *fout = out->data.ptr;
 for (i = 0 ; i < stride;i++,f++,fout++){
    *fout = sin(*f); 
}

虽然上述并不能给予你什么速度提升,因为SIN计算量放那。但要养成这个习惯。压缩纬度描述算法不单单是为了提高效率,同时是在约束你的存储结构。上述一维方式描述,则要求你的每行实际存储等于sizeof(float)*rows。

可能你会觉得我现在答非所问。我只能说,要想防止内存泄漏,编写程序的思维和习惯很重要。如果你用C++等面向对象语言,那是你的事情,如果你用C,C对内存具备强索引性,由此需要设计者对数据的内存分布具备严格的约束性。不单单是设计文档的约束,上述逻辑的代码,二维描述压成一维描述,本身也是一种约束。

现在回答你的正题:

如果是C语言,你的cvSinMat应该只是管道作用,你不需要考虑入口指针是否有效。你只要关注数据的操作。因此接口应该是

CvMat* cvSinMat(CvMat *pCMdst,CvMat * pCMsrc){
 

这里要养成两个习惯,如果是复杂的结构体,则缩写,指针,前缀小写p,通常 dst 在前,src在后。

此时,cvSinMat,就是一个管道,不存在新增数据空间,释放数据空间的动作。自然也不会由此引出内存泄漏的问题(事情能不做就不做,多做一样,就多一份错的可能)

cvCreateMat(rows, cols, a->type); 

这类的函数,在里面加上申请后的地址存储,同时atexit(cvDestroyMat)。此时即便时其他地方的exit,也可以保证依次释放对应空间。

中山野鬼
中山野鬼
回复 @徐少强 : 如果是技术问题,就在OSC吧,把妹问题。。貌似我退出江湖了。不过也可以支支招,但挨巴掌就不是我的责任了。哈。
天蚕变
天蚕变
太感激中山大侠了! 您太专业了,赞叹! 能加您QQ吗??
0
中山野鬼
中山野鬼
补充喷一句,openCV这种东西,只适合做原型。哈。。。。不过告诫一下,学院派的,如果想反喷我,建议你先琢磨琢磨自己有多少工程优化的底子。其实如果真有底子的,就不会反喷我了。。。
天蚕变
天蚕变
没有办法啊!只能用opencv做工程
0
三点以前不睡觉
三点以前不睡觉

引用来自“中山野鬼”的答案

补充喷一句,openCV这种东西,只适合做原型。哈。。。。不过告诫一下,学院派的,如果想反喷我,建议你先琢磨琢磨自己有多少工程优化的底子。其实如果真有底子的,就不会反喷我了。。。
貌似根本没人哦~
0
中山野鬼
中山野鬼

引用来自“何必认真呢”的答案

引用来自“中山野鬼”的答案

补充喷一句,openCV这种东西,只适合做原型。哈。。。。不过告诫一下,学院派的,如果想反喷我,建议你先琢磨琢磨自己有多少工程优化的底子。其实如果真有底子的,就不会反喷我了。。。
貌似根本没人哦~
这是好事情。有空折腾OPENCV,不如用MATLAB折腾原型。指望OPENCV做工程,太不靠谱了。。。。
0
天蚕变
天蚕变

引用来自“中山野鬼”的答案

openCV又有C,又有C++,所以比较混乱。另外,04年前后看过一些OPENCV的源码,结果发现太弱了,所以没怎么研究过。楼主我不知道你是用C还是用C++折腾。我这里只是基于C的思想给出我的一些观点。关于你上面的代码。

1、如果我没理解错,你的a->step,实际是a->data.ptr的数据存储的位宽。一般你应该这样写:

u32 step = a->step;
u32 stride = rows * step;
float *f = a->data.ptr;
float *fout = out->data.ptr;
 for (i = 0 ; i < stride;i++,f++,fout++){
    *fout = sin(*f); 
}

虽然上述并不能给予你什么速度提升,因为SIN计算量放那。但要养成这个习惯。压缩纬度描述算法不单单是为了提高效率,同时是在约束你的存储结构。上述一维方式描述,则要求你的每行实际存储等于sizeof(float)*rows。

可能你会觉得我现在答非所问。我只能说,要想防止内存泄漏,编写程序的思维和习惯很重要。如果你用C++等面向对象语言,那是你的事情,如果你用C,C对内存具备强索引性,由此需要设计者对数据的内存分布具备严格的约束性。不单单是设计文档的约束,上述逻辑的代码,二维描述压成一维描述,本身也是一种约束。

现在回答你的正题:

如果是C语言,你的cvSinMat应该只是管道作用,你不需要考虑入口指针是否有效。你只要关注数据的操作。因此接口应该是

CvMat* cvSinMat(CvMat *pCMdst,CvMat * pCMsrc){
 

这里要养成两个习惯,如果是复杂的结构体,则缩写,指针,前缀小写p,通常 dst 在前,src在后。

此时,cvSinMat,就是一个管道,不存在新增数据空间,释放数据空间的动作。自然也不会由此引出内存泄漏的问题(事情能不做就不做,多做一样,就多一份错的可能)

cvCreateMat(rows, cols, a->type); 

这类的函数,在里面加上申请后的地址存储,同时atexit(cvDestroyMat)。此时即便时其他地方的exit,也可以保证依次释放对应空间。

oschina真是藏龙卧虎啊!!!
返回顶部
顶部