Memory leak detected by Valgrind in cv::resize

System information (version)
  • OpenCV = 4.2.0
  • Operating System / Platform => Ubuntu 18.04
  • Compiler => CMake 3.10.2
  • Valgrind-3.17.0
Detailed description

I wrote a simple demo included cv::resize, but Valgrind detected that there might be a possible memory lost in cv::resize.
Here’s the code:

#include
#include "opencv2/opencv.hpp"
using namespace std;

int main(int argc, char* argv[])
{
cv::Mat a = cv::imread(R"(/home/images/consistency/gt_36723832.jpg)");
cv::Mat ccc;
cv::resize(a, ccc, {512, 256});
return 0;
}

Here’s the Valgrind output:

==85534== Memcheck, a memory error detector 
==85534== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. 
==85534== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info 
==85534== Command: ./bin/testbed 
==85534== Parent PID: 48914 
==85534== 
==85534== Warning: set address range perms: large range [0x626e000, 0x4fd2c000) (defined) 
==85534== 
==85534== HEAP SUMMARY: 
==85534== in use at exit: 1,015,399 bytes in 14,973 blocks 
==85534== total heap usage: 319,444 allocs, 304,471 frees, 49,509,681 bytes allocated 
==85534== 
==85534== 33,440 bytes in 95 blocks are possibly lost in loss record 14,264 of 14,264 
==85534== at 0x4C37B6D: calloc (vg_replace_malloc.c:1117) 
==85534== by 0x4013646: allocate_dtv (dl-tls.c:286) 
==85534== by 0x4013646: _dl_allocate_tls (dl-tls.c:530) 
==85534== by 0x508CA227: allocate_stack (allocatestack.c:627) 
==85534== by 0x508CA227: pthread_create@@GLIBC_2.2.5 (pthread_create.c:644) 
==85534== by 0x50A9834: cv::WorkerThread::WorkerThread(cv::ThreadPool&, unsigned int) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_core.so.4.2) 
==85534== by 0x50AB231: cv::ThreadPool::reconfigure_(unsigned int) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_core.so.4.2) 
==85534== by 0x50ABEBC: cv::parallel_for_pthreads(cv::Range const&, cv::ParallelLoopBody const&, double) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_core.so.4.2) 
==85534== by 0x50A73E4: cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_core.so.4.2) 
==85534== by 0x5CA0B98: void cv::resizeGeneric_<cv::HResizeLinear<unsigned char, int, short, 2048, cv::HResizeLinearVecU8_X4>, cv::VResizeLinear<unsigned char, int, short, cv::FixedPtCast<int, unsigned char, 22>, cv::VResizeLinearVec_32s8u> >(cv::Mat const&, cv::Mat&, int const*, void const*, int const*, void const*, int, int, int) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_imgproc.so.4.2) 
==85534== by 0x5CA9DAC: cv::hal::resize(int, unsigned char const*, unsigned long, int, int, unsigned char*, unsigned long, int, int, double, double, int) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_imgproc.so.4.2) 
==85534== by 0x5CAB19B: cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int) (in /home/images/third_party/opencv_4.2.0/lib/libopencv_imgproc.so.4.2) 
==85534== by 0x1109CA: main (in /home/images/testbed/bin/testbed) 
==85534== 
==85534== LEAK SUMMARY: 
==85534== definitely lost: 0 bytes in 0 blocks 
==85534== indirectly lost: 0 bytes in 0 blocks 
==85534== possibly lost: 33,440 bytes in 95 blocks 
==85534== still reachable: 981,959 bytes in 14,878 blocks 
==85534== suppressed: 0 bytes in 0 blocks 
==85534== Reachable blocks (those to which a pointer was found) are not shown. 
==85534== To see them, rerun with: --leak-check=full --show-leak-kinds=all 
==85534== 
==85534== For lists of detected and suppressed errors, rerun with: -s 
==85534== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Here’s the image loaded using imread:
gt_36723832

By the way, I’ve found that if I resize the image to {100, 200}, the lost disappeared.

This looks like Thread Local Storage (TLS) allocation. This memory will be allocated once for each thread in the thread pool and will not be freed until program exits. It should not cause problems unless you create new threads many times (internal OpenCV thread pool does not do this).

So this finding can be ignored unless the leak grows with e.g. each iteration of some loop. Try to repeat function call multiple times and check the size of the lost memory. If it grows - the leak is a problem.

1 Like

related: Memory leak detected by Valgrind in cv::resize · Issue #20145 · opencv/opencv · GitHub

you aren’t the first to run valgrind on complex code. valgrind is known to be overly broad in flagging things that may in fact be correct. always be aware of that. never treat valgrind’s output as bug reports.

1 Like