Recent

Author Topic: Saving fpspreadsheet to file causes an error  (Read 4579 times)

JD

  • Hero Member
  • *****
  • Posts: 1909
Saving fpspreadsheet to file causes an error
« on: September 29, 2012, 02:31:37 pm »
Hi there everyone,

After the recent changes to the FPC 2.6.1 compiler, the internal compiler error seems to have disappeared (for good, I hope  ::))

However, there seems to be a bug in the TsSpreadBIFF8Writer.WriteToFile procedure in the xlsbiff8.pas file used to create Excel 2003 files.

A error occurs on the line 'MemStream.Free' as seen in the code snippet below. The Excel file is created in spite of the error but I find it a little bothersome because it confuses the users of my application.

The error goes away once I commented out this line. But this means MemStream is created but not freed. Is this not a potential memory leak notwithstanding the fact that MemStream is reassigned to OleDocument.Stream?

Code: [Select]
{*******************************************************************
*  TsSpreadBIFF8Writer.WriteToFile ()
*
*  DESCRIPTION:    Writes an Excel BIFF8 file to the disc
*
*                  The BIFF 8 writer overrides this method because
*                  BIFF 8 is written as an OLE document, and our
*                  current OLE document writing method involves:
*
*                  1 - Writing the BIFF data to a memory stream
*
*                  2 - Write the memory stream data to disk using
*                      COM functions
*
*******************************************************************}
procedure TsSpreadBIFF8Writer.WriteToFile(const AFileName: string;
  AData: TsWorkbook; const AOverwriteExisting: Boolean);
var
  MemStream: TMemoryStream;
  OutputStorage: TOLEStorage;
  OLEDocument: TOLEDocument;
begin
  MemStream := TMemoryStream.Create;
  OutputStorage := TOLEStorage.Create;
  try
    WriteToStream(MemStream, AData);

    // Only one stream is necessary for any number of worksheets
    OLEDocument.Stream := MemStream;

    OutputStorage.WriteOLEFile(AFileName, OLEDocument, AOverwriteExisting, 'Workbook');
  finally
    //MemStream.Free;               <======= Commented out by JD a potential memory leak ?
    OutputStorage.Free;
  end;
end;

Any thoughts, suggestions?

JD
« Last Edit: September 29, 2012, 02:34:05 pm by JD »
Linux Mint - Lazarus 4.0/FPC 3.2.2,
Windows - Lazarus 4.0/FPC 3.2.2

mORMot 2, PostgreSQL & MariaDB.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Saving fpspreadsheet to file causes an error
« Reply #1 on: September 29, 2012, 02:43:44 pm »
Any thoughts, suggestions?

JD

I am guessing you get a sigsegv or something along those line try the following.

Code: [Select]
{*******************************************************************
*  TsSpreadBIFF8Writer.WriteToFile ()
*
*  DESCRIPTION:    Writes an Excel BIFF8 file to the disc
*
*                  The BIFF 8 writer overrides this method because
*                  BIFF 8 is written as an OLE document, and our
*                  current OLE document writing method involves:
*
*                  1 - Writing the BIFF data to a memory stream
*
*                  2 - Write the memory stream data to disk using
*                      COM functions
*
*******************************************************************}
procedure TsSpreadBIFF8Writer.WriteToFile(const AFileName: string;
  AData: TsWorkbook; const AOverwriteExisting: Boolean);
var
  MemStream: TMemoryStream;
  OutputStorage: TOLEStorage;
  OLEDocument: TOLEDocument;
begin
  MemStream := TMemoryStream.Create;
  OutputStorage := TOLEStorage.Create;
  try
    WriteToStream(MemStream, AData);

    // Only one stream is necessary for any number of worksheets
    OLEDocument.Stream := MemStream;

    OutputStorage.WriteOLEFile(AFileName, OLEDocument, AOverwriteExisting, 'Workbook');
  finally
    OLEDocument.Stream := nil;//make sure that it doesn't try to access the stream after is freed.
    MemStream.Free;               
    OutputStorage.Free;
  end;
end;

To be sure take a look on the OLEDocument.Stream property what it does in the SetStream (or something along those lines) setter method used if it has code along the lines of
Code: [Select]
begin
    If LocalStreamVar = AValue then exit;
    LocalStreamVar := AValue;
end;
then the above suggestion should stop the error, If on the other hand you see code that it copies the stream data in an internal structure then probably the above will not fix it either.

Regards
Jo.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

JD

  • Hero Member
  • *****
  • Posts: 1909
Re: Saving fpspreadsheet to file causes an error
« Reply #2 on: October 01, 2012, 06:43:48 pm »
It dosen't work. The error remains there. I'll just leave it like that until I can contact the package maintainer or wait & see if it will be corrected in SVN.

Thanks for your suggestion.
Linux Mint - Lazarus 4.0/FPC 3.2.2,
Windows - Lazarus 4.0/FPC 3.2.2

mORMot 2, PostgreSQL & MariaDB.

 

TinyPortal © 2005-2018