memory leak in DcmElement::getPartialValue

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
Shaeto
Posts: 143
Joined: Tue, 2009-01-20, 17:50
Location: CA, USA
Contact:

memory leak in DcmElement::getPartialValue

#1 Post by Shaeto » Mon, 2021-09-06, 13:16

getPartialValue does not destroy readStream if stream status is not okay after creation

Code: Select all

    // initialize the cache with new stream
    if (!readStream)
    {
      readStream = fLoadValue->create();
    
      // check that read stream is non-NULL
      if (readStream == NULL) return EC_InvalidStream;

      // check that stream status is OK
      if (readStream->status().bad()) return readStream->status();

      cache->init(readStream, this);
    }
here is a simplest test, i know situation is strange but live in big application is not so easy :)
you'll need any dicom file test.dcm having PixelData in root dataset

Code: Select all

#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmdata/dctk.h"

int main()
{
    std::cout << "beginning" << std::endl;

    DcmFileFormat ff;

    OFString test_filename = "test.dcm";

    if (ff.loadFile(test_filename, EXS_Unknown, EGL_noChange, DCM_MaxReadLength, ERM_autoDetect).good())
    {
        DcmElement *e = NULL;

        if (ff.getDataset()->findAndGetElement(DCM_PixelData, e).good())
        {

            if (rename(test_filename.c_str(), (test_filename + ".bak").c_str()) == 0)
            {
                std::cout << "renamed" << std::endl;
            }

            char buffer[1024];

            unsigned long size = e->getLength();
            printf("%04x,%04x - %lu bytes\n", e->getGTag(), e->getETag(), size);
            OFCondition result = e->getPartialValue(buffer, 0, std::min(size, sizeof(buffer)));

            if (result.bad())
            {
                std::cout << "failed to read value: " << result.text() << std::endl;
            }
            else
            {
                std::cout << "partially read" << std::endl;
            }
        } else {
            std::cout << "no pixels to read" << std::endl;
        }
    } else {
        std::cout << "can't read file " << test_filename << std::endl;
    }

    return 0;
}
valgrind --tool=memcheck --malloc-fill=CC --leak-check=full --show-leak-kinds=all ./test

==21279==
==21279== HEAP SUMMARY:
==21279== in use at exit: 139 bytes in 3 blocks
==21279== total heap usage: 86,021 allocs, 86,018 frees, 2,496,478 bytes allocated
==21279==
==21279== 9 bytes in 1 blocks are indirectly lost in loss record 1 of 3
==21279== at 0x4C34F0B: malloc (vg_replace_malloc.c:307)
==21279== by 0x5F6D80D: strdup (strdup.c:42)
==21279== by 0x538AEE7: OFFilename::OFFilename(OFFilename const&) (offile.cc:93)
==21279== by 0x4FCDBAF: DcmInputFileStream::DcmInputFileStream(OFFilename const&, long) (dcistrmf.cc:162)
==21279== by 0x4FCDB1A: DcmInputFileStreamFactory::create() const (dcistrmf.cc:154)
==21279== by 0x4FA9546: DcmElement::getPartialValue(void*, unsigned int, unsigned int, DcmFileCache*, E_ByteOrder) (dcelem.cc:1819)
==21279== by 0x4019C1: main (test.cpp:28)
==21279==
==21279== 26 bytes in 1 blocks are indirectly lost in loss record 2 of 3
==21279== at 0x4C34F0B: malloc (vg_replace_malloc.c:307)
==21279== by 0x5F6D80D: strdup (strdup.c:42)
==21279== by 0x4F431B8: OFCondition::operator=(OFCondition const&) (ofcond.h:242)
==21279== by 0x4FCD34B: DcmFileProducer::DcmFileProducer(OFFilename const&, long) (dcistrmf.cc:54)
==21279== by 0x4FCDB98: DcmInputFileStream::DcmInputFileStream(OFFilename const&, long) (dcistrmf.cc:162)
==21279== by 0x4FCDB1A: DcmInputFileStreamFactory::create() const (dcistrmf.cc:154)
==21279== by 0x4FA9546: DcmElement::getPartialValue(void*, unsigned int, unsigned int, DcmFileCache*, E_ByteOrder) (dcelem.cc:1819)
==21279== by 0x4019C1: main (test.cpp:28)
==21279==
==21279== 139 (104 direct, 35 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==21279== at 0x4C35586: operator new(unsigned long) (vg_replace_malloc.c:342)
==21279== by 0x4FCDAFC: DcmInputFileStreamFactory::create() const (dcistrmf.cc:154)
==21279== by 0x4FA9546: DcmElement::getPartialValue(void*, unsigned int, unsigned int, DcmFileCache*, E_ByteOrder) (dcelem.cc:1819)
==21279== by 0x4019C1: main (test.cpp:28)
==21279==
==21279== LEAK SUMMARY:
==21279== definitely lost: 104 bytes in 1 blocks
==21279== indirectly lost: 35 bytes in 2 blocks
==21279== possibly lost: 0 bytes in 0 blocks
==21279== still reachable: 0 bytes in 0 blocks
==21279== suppressed: 0 bytes in 0 blocks

J. Riesmeier
DCMTK Developer
Posts: 2313
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: memory leak in DcmElement::getPartialValue

#2 Post by J. Riesmeier » Thu, 2021-09-09, 06:24

Thank you for the detailed report. I've added this issue to our tracker: https://support.dcmtk.org/redmine/issues/1010

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest