绝对可以使用cv :: Mat指针,但是(与所有指针一样)您必须格外小心地删除创建的对象,以再次释放分配的内存。

在您的示例代码中,尚不清楚是否将在任何地方删除其指针在函数中返回的对象。 如果不是这种情况,则cv :: Mat像素数据的引用计数将无法按预期方式工作,此外,cv :: Mat对象本身也会泄漏一些(较小的)内存。 如此简短:对于每个new cv::Mat必须有一个delete ,因此,如果外部函数中有一个new ,也许您必须为其调用一个delete (如果该函数不是某些智能类功能本身所做的,后来)。 更具体地讲, Mat* m = new Mat ( *MatPointerReturningFunc(..))将创建一个新的cv :: Mat对象,因为可以稍后将其删除,但该对象返回的指针丢失了。 尝试cv::Mat * returnedPtr = MatPointerReturningFunc(..); 跟cv::Mat * m = new cv::Mat(*returnedPtr); 如果您要创建一个新的Mat对象(或仅使用returnPtr而不创建新对象)。

这是一些示例代码,带有2个不同的Mat Ptr返回函数,以及一些有或没有泄漏访问它们的方法。

值得一提的是,使用指针的“最佳”方法通常是智能指针,由OpenCV明确给出。 但是更好的是不要对cv :: Mat对象使用Pointers,因为它不那么容易出错,并且没有太多开销。 引用计数非常好,您通常不使用int或std::vector或std::string类的指针作为指针;)

cv::Mat* MatPointerReturningFunc()

{

// this function allocates new memory by first creating a new cv::Mat object on heap (just some bytes for the Mat header)

// and second by allocating new reference counted data in that cv::Mat object (pixel memory = 640*480*3 bytes)

cv::Mat * functionMat = new cv::Mat(480, 640, CV_8UC3, cv::Scalar(rand()%255, rand()%255, rand()%255));

return functionMat;

}

cv::Mat* MatPointerReturningFunc2(cv::Mat * input)

{

// this function does not allocate new memory on the heap, just modifies the input data

cv::circle(*input, cv::Point(320, 240), 100, cv::Scalar(rand() % 255, rand() % 255, rand() % 255), -1);

return input;

}

int main(int argc, char* argv[])

{

while (cv::waitKey(0) != 'q')

{

cv::Mat * mainMat;

cv::Mat * anotherMat;

// this will not leak, because the memory which was allocated in the function, is destroyed afterwards

// and the reference counter of the openCV Mat pixel-data is decremented

if (true)

{

mainMat = MatPointerReturningFunc();

cv::imshow("main", *mainMat);

delete mainMat;

}

// this will leak because the returned Mat object will not be deleted, only the here created one - that's why the reference counting is stuck at one referenced object

if (false)

{

mainMat = new cv::Mat(*MatPointerReturningFunc());

delete mainMat;

}

// this will not leak, since all references to the Mat data are destroyed (the returned Mat and the locally created new Mat)

if (true)

{

mainMat = MatPointerReturningFunc();

cv::Mat * anotherMat = new cv::Mat(*mainMat);

cv::imshow("main", *mainMat);

cv::imshow("another", *anotherMat);

cv::imshow("another", *anotherMat);

delete mainMat;

delete anotherMat;

}

// this will not leak because all references are destroyed

if (true)

{

mainMat = MatPointerReturningFunc();

cv::imshow("main", *mainMat);

anotherMat = new cv::Mat(mainMat->clone());

cv::imshow("another", *anotherMat);

delete mainMat;

delete anotherMat;

}

// now here we work with the second function which does not allocate new memory but only modifies the input matrix

if (true)

{

// first we have to allocate memory, otherwise the input mat can't be modified ;)

mainMat = new cv::Mat(480, 640, CV_8UC3, cv::Scalar(255, 255, 255));

cv::imshow("main", *mainMat);

// this does not leak because the second functions doesn't allocate new memory:

// however we have to delete mainMat later, because we created it before.

if (true)

{

anotherMat = MatPointerReturningFunc2(mainMat);

cv::imshow("another", *anotherMat);

}

// this does not leak because we delete the new created Mat object here and the before created mainMat later

if (true)

{

anotherMat = new cv::Mat(*MatPointerReturningFunc2(mainMat));

cv::imshow("another", *anotherMat);

delete anotherMat;

}

// this does not leak because we delete the new created Mat object here and the before created mainMat later

// in fact, this way will allocate new pixel data because of the clone(), but we will free the memory with `delete anotherMat`directly

if (true)

{

anotherMat = new cv::Mat(MatPointerReturningFunc2(mainMat)->clone());

cv::imshow("another", *anotherMat);

delete anotherMat;

}

// since we created the object and allocated memory, we have to give it free here again

delete mainMat;

}

// in fact, if you WANT to use Pointers with OpenCV Mat objects you should use smart pointers.

// OpenCV has its own smart pointers, but I guess you could use any other smart pointers

// create a Mat object on the heap, allocate pixel data and access all this by a smart pointer!

cv::Ptr<:mat> smartPtr = new cv::Mat(480, 640, CV_8UC3, cv::Scalar(rand()%255, rand()%255, rand()%255) );

cv::imshow("smart pointer", *smartPtr);

// no need to delete the created Mat on the smart pointer, because the smart pointer has its own reference counting

}

return 0;

}

mat 释放_c++ - OpenCV无法释放Mat *内存 - 堆栈内存溢出相关推荐

  1. opencv mat 修改_C++ opencv矩阵和pytorch tensor的互相转换

    矩阵和tensor相互转换 cvmat到tensor tips:这里主要要注意的就是在opencv和pytorch中存储顺序的差异 cv::cvtColor(frame, frame, CV_BGR2 ...

  2. opencv java 去干扰_java - OpenCV Java修补图像格式要求 - 堆栈内存溢出

    一直试图让修复工作在Android上进行, int height = (int) viewMat.size().height; int width = (int) viewMat.size().wid ...

  3. android 自定义录像机,android-camera2 - 将自定义捕获请求构建器选项设置为使用Camera2 API捕获图像以使用OpenCV库进行摄像机校准 - 堆栈内存溢出...

    我们正在使用Camera2 API捕获N张图像,而未设置任何自定义捕获请求构建器选项. 我们正在使用这些图像通过OpenCV Android库411进行相机校准. 然后,我们正在使用OpenCV An ...

  4. python opencv 录制视频_python - 使用Opencv Python多线程录制视频 - 堆栈内存溢出

    我认为您的工作方向正确,但是我无法使用您的代码保存文件. 这是一个使用多线程获取帧的视频流到视频小部件. 每个摄像机流都有两个线程: 线程#1-专用于仅读取摄像机流中的帧. 线程#2-专用于处理帧(显 ...

  5. python共享内存mmap_python - IPC在单独的Docker容器中的Python脚本之间共享内存 - 堆栈内存溢出...

    问题 我已经编写了一个神经网络分类器,该分类器可以获取海量图像(每张图像约1-3 GB),将其打补丁,然后分别通过网络传递这些补丁. 培训的进行过程非常缓慢,因此我对其进行了基准测试,发现用大约50秒 ...

  6. 前端面试题讲解(THIS、构造函数、面向对象、堆栈内存以及闭包)

    视频地址:https://www.bilibili.com/video/av24383268/?p=13 02. JS中的严格模式和ARG映射机制 EXP1 EXP2 映射机制 严格模式 03. 逻辑 ...

  7. JS函数简单的底层原理 -变量重复声明无效,隐式申明,变量提升,函数提升,以及堆栈内存的变化

    JS函数简单的底层原理 (个人理解): 1. 已经使用var申明且赋值,若再次申明,则第二次申明(不赋值)无效. 2.在同一个作用域下,只要是发生了同名,且变量完成赋值,后者会覆盖前者.存在两个相同的 ...

  8. OpenCv2 学习笔记(1) Mat创建、复制、释放

    OpenCV和VS2013的安装图文教程网上有很多,建议安装好之后,用VS2013建立一个空工程,用属性管理器分别新建一个对应debug和release工程的props配置文件,以后直接根据工程需要添 ...

  9. 【从零学习OpenCV 4】Mat类介绍

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

最新文章

  1. Bitsocket——BCH实时API,为BCH带来无限可能
  2. golang 编译提示 cannot assign interface {} 和golang断言使用
  3. euler‘s formula
  4. restful api上传文件(基础)-springboot
  5. java 打包jar文件以在没有安装JDK或JRE的机子上运行
  6. Attribute is missing the Android namespace prefix
  7. Maven 项目的 org.junit.Test 获取不到(转载)
  8. mysql 索引查询_mysql索引的建立和查询语句优化
  9. nginx实现301(加密)跳转和200跳转
  10. [转]VC6.0编译fltk-1.1.10
  11. 2021-08-02 INSERT INTO插入语句
  12. BAT54C 二极管是如何工作的?
  13. VMP2.0版本带壳调试教程
  14. proteus中ISIS软件的各种器件的添加
  15. 利用Echarts+阿里云地图选择器绘制可交互的行政区划地图
  16. background_dump_dest 参数
  17. 亚控科技工作中的编程知识小积累
  18. 2022年,Lazada开店要交多少钱
  19. SSL/TLS协议详解(中)——证书颁发机构
  20. 计算机通过网线连接不到网络,电脑有网线连不上网怎么解决

热门文章

  1. 学习seo必须学习什么?
  2. mac 下几款解压缩工具
  3. python使用多线程读写数据到文件2
  4. 淘宝网站简易分析评价
  5. 新唐M0内核。接口的TTL电平和斯密特电平的使用
  6. 批处理使用问题处理(逐步添加)
  7. 2021年健康医疗、专业服务和检测认证等行业将有较大用人增长;香港上市公司女性董事比例落后 | 美通企业日报...
  8. Facebook SDK For Unity
  9. 读薄《深入理解 Java 虚拟机》 JVM 的内存分配策略
  10. Anaconda环境下,处理ERROR 1: PROJ: pj_obj_create: Cannot find proj.db问题