glassechidna / zxing-cpp

ZXing C++ Library
Apache License 2.0
605 stars 436 forks source link

Memory leak using HybridBinarizer #72

Open logidelic opened 5 years ago

logidelic commented 5 years ago

I've noticed quite a large memory leak using the Hybrid Binarizer (at least under certain circumstances). I've started debugging but so far haven't figured it out. Any ideas about this? Below is a repro (will eat up several GB quickly) as well as some valgrind output. Any help would be appreciated.

Valgrind:

==14603== 13,160,000 bytes in 7 blocks are possibly lost in loss record 1,401 of 1,408
==14603==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14603==    by 0x4E7FC28: zxing::BitMatrix::BitMatrix(int, int) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4E88FFB: zxing::HybridBinarizer::getBlackMatrix() (in /usr/local/lib/libzxing.so)
==14603==    by 0x4E7E771: zxing::BinaryBitmap::getBlackMatrix() (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EE05F6: zxing::qrcode::QRCodeReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EA9211: zxing::MultiFormatReader::decodeInternal(zxing::Ref<zxing::BinaryBitmap>) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EAA40C: zxing::MultiFormatReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) (in /usr/local/lib/libzxing.so)
==14603==    by 0x113D31: read_image(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, zxing::Ref<zxing::LuminanceSource>, bool, bool, bool) (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603==    by 0x114679: decodeDataMatrix[abi:cxx11](cv::Mat const&) (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603==    by 0x1148B4: main (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603== 
==14603== 148,527,568 (4,128 direct, 148,523,440 indirect) bytes in 86 blocks are definitely lost in loss record 1,406 of 1,408
==14603==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14603==    by 0x4E88FEA: zxing::HybridBinarizer::getBlackMatrix() (in /usr/local/lib/libzxing.so)
==14603==    by 0x4E7E771: zxing::BinaryBitmap::getBlackMatrix() (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EE05F6: zxing::qrcode::QRCodeReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EA9211: zxing::MultiFormatReader::decodeInternal(zxing::Ref<zxing::BinaryBitmap>) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EAA40C: zxing::MultiFormatReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) (in /usr/local/lib/libzxing.so)
==14603==    by 0x113D31: read_image(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, zxing::Ref<zxing::LuminanceSource>, bool, bool, bool) (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603==    by 0x114679: decodeDataMatrix[abi:cxx11](cv::Mat const&) (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603==    by 0x1148B4: main (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603== 
==14603== 152,287,568 (4,128 direct, 152,283,440 indirect) bytes in 86 blocks are definitely lost in loss record 1,408 of 1,408
==14603==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14603==    by 0x4E88FEA: zxing::HybridBinarizer::getBlackMatrix() (in /usr/local/lib/libzxing.so)
==14603==    by 0x4E7E771: zxing::BinaryBitmap::getBlackMatrix() (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EE05F6: zxing::qrcode::QRCodeReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EA9211: zxing::MultiFormatReader::decodeInternal(zxing::Ref<zxing::BinaryBitmap>) (in /usr/local/lib/libzxing.so)
==14603==    by 0x4EAA40C: zxing::MultiFormatReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) (in /usr/local/lib/libzxing.so)
==14603==    by 0x113D31: read_image(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, zxing::Ref<zxing::LuminanceSource>, bool, bool, bool) (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603==    by 0x11454D: decodeDataMatrix[abi:cxx11](cv::Mat const&) (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)
==14603==    by 0x1148B4: main (in /media/user/data/doc/dev/test/zxing-opencv/build/zxtest)

Repro:

#include <thread>
#include <exception>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <zxing/common/Counted.h>
#include <zxing/Binarizer.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/Result.h>
#include <zxing/ReaderException.h>
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/Exception.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/DecodeHints.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/MatSource.h>
#include <zxing/common/HybridBinarizer.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/multi/qrcode/QRCodeMultiReader.h>
#include <zxing/multi/ByQuadrantReader.h>
#include <zxing/multi/MultipleBarcodeReader.h>
#include <zxing/multi/GenericMultipleBarcodeReader.h>

using namespace cv;
using namespace std;
using namespace zxing;
using namespace zxing::multi;
using namespace zxing::qrcode;

void decodeDataMatrix(const Mat& imgOrig) {
  Mat img;
  cvtColor(imgOrig, img, CV_RGB2GRAY);
  Ref<LuminanceSource> source = MatSource::create(img);

  try {
    Ref<Binarizer> binarizer;
    binarizer = new HybridBinarizer(source);
    DecodeHints hints(DecodeHints::DEFAULT_HINT);
    hints.setTryHarder(false);
    Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));

    // Decode single code
    Ref<Reader> reader(new MultiFormatReader);
    reader->decode(binary, hints);
    //results = vector<Ref<Result> >(1, reader->decode(binary, hints));
  } catch (const ReaderException& e) {
    cout << "zxing::ReaderException: " << string(e.what()) << endl;
  } catch (const zxing::IllegalArgumentException& e) {
    cout << "zxing::IllegalArgumentException: " << string(e.what()) << endl;
  } catch (const zxing::Exception& e) {
    cout << "zxing::Exception: " << string(e.what()) << endl;
  } catch (const std::exception& e) {
    cout << "std::exception: " << string(e.what()) << endl;
  } catch(...) {
    cout << "exception" << endl;
  }
}

int main() {

    while(true) {
        Mat mat(5000, 3000, CV_8UC3, Scalar(0,0,0));
        decodeDataMatrix(mat);
        cout << "..." << endl;
    }

    return 0;
}