OpenCV中原Mat被释放后其生成的submat能否继续安全使用?
问题结论
你提供的示例代码是完全安全的,父Mat调用release()之后,对应的submat仍然可以正常使用,不会出现野指针、内存访问错误这类问题。
核心原理
OpenCV的Mat设计本身就考虑到了共享数据的场景:
- 每个
Mat分为两个独立部分:轻量的头部(存储图像宽高、通道数、数据起始指针等元信息)和堆上分配的像素数据块,数据块自带引用计数,所有共享同一份数据的Mat都会共同维护这个计数。 - 调用
submat()生成ROI时,不会复制像素数据,仅会创建一个新的Mat头部,指向原数据块中ROI对应的起始地址,同时把数据块的引用计数+1。 - 调用父Mat的
release()方法时,只会把父Mat对应的数据块引用计数减1,同时把父Mat自身的头部置空。此时你的roi仍然持有该数据块的有效引用,引用计数大于0,像素数据块不会被系统回收,roi指向的内存区域始终是合法的。
注意事项
- 只有当所有共享该数据块的
Mat对象都被释放/调用release()后,像素数据块才会被真正回收。 - 如果你需要修改ROI的内容且不希望影响其他共享同个数据块的
Mat,才需要调用clone()生成独立的拷贝,否则你当前的用法完全可以实现节省时间和内存的需求,不存在安全风险。
内容的提问来源于stack exchange,提问作者vatbub
相关产品推荐
相关产品推荐

