【问题标题】:How to completely free memory of cv::Mat in C++如何在 C++ 中完全释放 cv::Mat 的内存
【发布时间】:2017-01-12 22:39:35
【问题描述】:

当我尝试创建一个 cv::Mat 并在之后释放它(代码如下)时,我仍然有(根据 valgrind)每个像素大约 1 个字节的内存泄漏。

有人知道如何正确释放 cv::Mat 的内存吗?

感谢您的分析:)

代码:

int main(int argc, char** argv)
{
  cv::Mat* matrx = new cv::Mat(1000,1000,CV_8UC1,0.);
  matrx->release();
  delete matrx;
  return 0;
}

瓦尔格林:

[...]
==29420==    1,000,028 bytes in 1 blocks are definitely lost in loss record 372 of 372
==29420==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29420==    by 0x5438877: cv::fastMalloc(unsigned long) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==29420==    by 0x536FE2A: cv::Mat::create(int, int const*, int) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==29420==    by 0x426FB5: cv::Mat::create(int, int, int) (mat.inl.hpp:663)
==29420==    by 0x426ECD: cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&) (mat.inl.hpp:347)
==29420==    by 0x425A09: main (main.cpp:18)
==29420== 
==29420== LEAK SUMMARY:
==29420==    definitely lost: 1,000,028 bytes in 1 blocks
==29420==    indirectly lost: 0 bytes in 0 blocks
==29420==      possibly lost: 5,072 bytes in 95 blocks
==29420==    still reachable: 304,758 bytes in 1,348 blocks
==29420==         suppressed: 0 bytes in 0 blocks
[...]

【问题讨论】:

  • 由于内部引用计数,使用指向Mat 对象的指针通常是个坏主意。只需将它们放在堆栈上:int main(){Mat a(10,10,CV_8UC1); return 0;}
  • @Miki 我只是减少了我的代码以使问题更容易并找到问题。我需要不同类的矩阵,所以需要一个指针。甚至 std::shared_ptr<:mat> 也没有解决问题
  • 所以让一个类拥有它作为非指针,并给其余类一个指针/引用。
  • 降级到 OpenCV 2.4.8 后问题消失了。我在 GitHub 上报告了一个问题。 github.com/opencv/opencv/issues/7238
  • 我建议使用 2.4.8,因为 valgrind 输出中的跟踪列出了 2.4.8 中的 SO。这可能是根本原因。您为 3.1 编译,但使用的运行时是 2.4.8。

标签: c++ opencv memory-leaks opencv-mat


【解决方案1】:

来自 opencv github 的反馈似乎很明确:您使用 OpenCV 3.x 编译,但在运行时使用 OpenCV 2.4.8。由于它们不是二进制兼容的,它不能正确释放cv::Mat。让我们将您的LD_LIBRARY_PATH 导出到用于编译的OpenCV 3.x 的OCV_DIST/lib。

请注意,如果您使用delete 指针,您甚至不需要之前的release()。

【讨论】:

    【解决方案2】:

    从文档页面引用以下内容:(http://docs.opencv.org/2.4.9/modules/core/doc/basic_structures.html#mat-release):

    void Mat::release() 该方法递减与矩阵数据相关联的参考计数器。当引用计数器达到 0 时,矩阵数据被释放,数据和引用计数器指针被设置为 NULL。

    上面的意思是当你做“delete matrx;”时您正在尝试删除已经指向 NULL 的内存区域,这会产生运行时错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      • 1970-01-01
      • 2018-01-10
      • 2017-06-07
      • 2022-08-14
      相关资源
      最近更新 更多