A memory leak in Delphi XE3 when an error occurs while inserting into sqlite db

... Query: TSQLQuery ... Query.SQL.Clear; Query.SQL.Add('INSERT INTO pumps'#13#10 + 'VALUES (NULL, :title, :power)'); Query.ParamByName('title').AsString:= title; Query.ParamByName('power').AsFloat:= power; try Query.ExecSQL; except on E: Exception do begin ShowMessage(E.Message); end; end; 

The request is associated with SQLConnection with driver = Sqlite. All operations really work, but when I try to insert a unique value in a column with a unique index, I get an exception due to the value. OK, my code catches it and shows the message β€œThe column heading is not unique”, but before the debugger shows me this TWICE exception. When I close the program, the memory manager reports memory leaks, and these leaks:

  • 21 - 28 bytes: UnicodeString x 4
  • 61 - 68 bytes: TDBXSqliteCommand x2
  • 69 - 76 bytes: TDBXMorphicCommand x 2
  • 221 - 236 bytes: Unknown x 2

Can this be avoided?

UPD: I used FastMM4 to get a verbose log, and below is part of a memory leak:

 A memory block has been leaked. The size is: 68 This block was allocated by thread 0xB18, and the stack trace (return addresses) at the time was: 4068A6 [System.pas][System][@GetMem$qqri][4203] 4082BB [System.pas][System][TObject.NewInstance$qqrv][14969] 4089D2 [System.pas][System][@ClassCreate$qqrpvzc][16231] 7D5A91 [Data.DbxSqlite.pas][Data.DbxSqlite][Dbxsqlite.TDBXSqliteCommand.$bctr$qqrp26Data.Dbxcommon.TDBXContextp35Data.Dbxsqlite.TDBXSqliteConnection][567] 6E3DFE [Data.DBXCommon][Generics.Collections.%TDictionary__2$20System.UnicodeStringp32Data.Dbxcommon.TDBXCreateCommand%.GetBucketIndex$qqrx20System.UnicodeStringi] 7D4C8E [Data.DbxSqlite.pas][Data.DbxSqlite][Dbxsqlite.TDBXSqliteDriver.CreateSqliteCommand$qqrp26Data.Dbxcommon.TDBXContextp29Data.Dbxcommon.TDBXConnectionp26Data.Dbxcommon.TDBXCommand][295] 6CE4DA [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXDriver.CreateMorphCommand$qqrp26Data.Dbxcommon.TDBXContextp29Data.Dbxcommon.TDBXConnectionp26Data.Dbxcommon.TDBXCommand][7569] 6D5177 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXDelegateDriver.CreateMorphCommand$qqrp26Data.Dbxcommon.TDBXContextp29Data.Dbxcommon.TDBXConnectionp26Data.Dbxcommon.TDBXCommand][11061] 6D09F4 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXConnection.CreateMorphCommand$qqrp26Data.Dbxcommon.TDBXCommand][8480] 6D1C21 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXMorphicCommand.DerivedOpen$qqrv][9084] 6D1974 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXCommand.Open$qqrv][8962] The block is currently used for an object of class: TDBXSqliteCommand 
+6
source share
1 answer

I run tests using the dbXpress SQLite and MySQL driver (XE3), and your code just leaks using SQLite (also get a double exception in debug mode), but it is not with MySQL .

IMHO is a bug that should be reported in QC.

Stack trace when the first exception occurs in the debugger

 :769cc41f KERNELBASE.RaiseException + 0x58 Data.DBXCommon.TDBXContext.Error(???,'column title is not unique') Data.DbxSqlite.CheckError(19,???,$2F12738) Data.DbxSqlite.TDBXSqliteCommand.DerivedExecuteQuery Data.DBXCommon.TDBXCommand.ExecuteQuery Data.DBXCommon.TDBXMorphicCommand.ExecuteQuery Data.SqlExpr.TCustomSQLDataSet.ExecuteStatement Data.SqlExpr.TCustomSQLDataSet.ExecSQL(???) Data.SqlExpr.TSQLQuery.ExecSQL(???) Main_ViewU.TForm1.RunQuery($2E7B870,'Title',10) Main_ViewU.TForm1.Button1Click($2E85AD0) 

Stack trace when a second error occurs in the debugger

 :769cc41f KERNELBASE.RaiseException + 0x58 // <-- Exception interrupts Destroy Data.DBXCommon.TDBXContext.Error(???,'column title is not unique') Data.DbxSqlite.CheckError(19,???,$2F12738) Data.DbxSqlite.TDBXSqliteCommand.DerivedClose Data.DBXCommon.TDBXCommand.Close Data.DBXCommon.TDBXMorphicCommand.DerivedClose Data.DBXCommon.TDBXCommand.Close Data.DBXCommon.TDBXCommand.Destroy // <-- DESTROY Data.DBXCommon.TDBXMorphicCommand.Destroy // <-- DESTROY System.TObject.Free Data.SqlExpr.TCustomSQLDataSet.CloseStatement Data.SqlExpr.TCustomSQLDataSet.InternalFreeCommand Data.SqlExpr.TCustomSQLDataSet.FreeCommand Data.SqlExpr.TCustomSQLDataSet.ExecSQL(???) Data.SqlExpr.TSQLQuery.ExecSQL(???) Main_ViewU.TForm1.RunQuery($2E7B870,'Title',10) Main_ViewU.TForm1.Button1Click($2E85AD0) 

And this causes a memory leak ...

+3
source

All Articles