[Lazarus] Buffer dealocating between program and C++ library

Leonardo M. Ramé l.rame at griensu.com
Wed May 11 20:35:40 CEST 2011


Hi, I'm using a C++ library created by me, with a function that let me get an image buffer. 
I use that buffer to do some processing, then I can tell the library to delete the buffer.

In Linux, I never had an issue between my Lazarus program and that
library, but yesterday I decided to port it to Windows, and found the
buffer is never deleted, causing a "Microsoft Visual C++ Runtime
library, runtime error....". The library is compiled with Mingw32.

After having found the error, I created a C++ program that calls the
problematic method 1000 times, and noted the memory is handled
correctly, then I made a simple FPC program that does the same thing,
and found the same behavior as in Lazarus.

Here are the signatures for the functions exported by the library:

  TgetDicomImage = function(const ADicomImage: Pointer; out buffer: Pointer;
    out bufSize: longint; ALeft, ATop: double; var AWidth, AHeight: double): integer; cdecl;

  TdeleteBuffer = procedure(ABuffer: PByte); cdecl;


And here is a snippet of the code I use to test the function:


  Pointer(lGetDicomImage) := GetProcAddress(lLibHandle, 'getDicomImageBufferEx');
  Pointer(lDeleteBuffer) := GetProcAddress(lLibHandle, 'deleteBuffer');

  for I := 0 to 1000 do
  begin
    if @lGetDicomImage <> nil then
    begin
      lWidth := 900;
      lHeight := 400;
      lBuffer := nil;
      lBufSize:= 0;
      if lGetDicomImage(lDicomImage, lBuffer, lBufSize, lLeft, lTop, lWidth, lHeight) = 1 then
      begin

        // ---   buffer processing  --
        // ...
        // --- end buffer processing --

        if @lDeleteBuffer <> nil then
          lDeleteBuffer(lBuffer); // <----- memory keeps increasing here.
      end;
    end;
  end;

For those interested in the C++ functions:

  int getImageBufferEx(void * imagen, void * &buffer, unsigned long&
  bufSize, double left, double top, double &width, double &height)
  {
     DicomImageHandler * imgHandler = (DicomImageHandler *)imagen;
     int lResult = -1;
     if(imgHandler->getDicomImage()->getStatus() == EIS_Normal)
     {
       double lZoom = imgHandler->getZoomFactor();
       DicomImage * lOrigImage = imgHandler->getDicomImage()->createClippedImage(left, top, width, height, 65535);
       DicomImage * clippedImage = lOrigImage->createScaledImage(lZoom);
       width = clippedImage->getWidth();
       height = clippedImage->getHeight();
       bufSize = clippedImage->getOutputDataSize();
       buffer = new Uint16[bufSize];
       if(clippedImage->getOutputData((void *)(buffer), bufSize, 8))
         lResult = 1;
       delete clippedImage;
       delete lOrigImage;
     }
     return lResult;
  }


  void deleteBuffer(void * &buffer)
  {
    delete [] (Uint16 *)buffer;
    buffer = NULL;
  }


Please, tell me if you find something that can be causing the memory
leaks.

Thanks in advance,
-- 
Leonardo M. Ramé
http://leonardorame.blogspot.com




More information about the Lazarus mailing list