6
...
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;

クエリはdriver=SqliteでSQLConnectionにリンクされています。すべての操作は機能しますが、一意でないインデックスを持つ列に一意でない値を挿入しようとすると、値の存在に関する例外が発生します。OK、私のコードはそれをキャッチし、「列のタイトルは一意ではありません」というメッセージを表示しますが、デバッガーがその例外を2回表示する前に。プログラムを閉じると、メモリマネージャはメモリリークについて通知します。リークは次のとおりです。

  • 21〜28バイト:UnicodeString x 4
  • 61〜68バイト:TDBXSqliteCommand x2
  • 69〜76バイト:TDBXMorphicCommand x 2
  • 221-236バイト:不明x 2

それを回避することは可能ですか?

UPD:FastMM4を使用して詳細なログを取得しました。以下は、1つのメモリリークに関する部分です。

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
4

1 に答える 1

3

dbXpress SQLiteおよびMySQLドライバー (XE3) でテストを実行すると、 SQLite でコードがリークします (デバッグ モードでも二重の例外が発生します) が、MySQL ではリークしません

IMHO これは QC に報告する必要があるバグです。

デバッガーでの最初の例外発生時のスタック トレース

: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)

デバッガーでの2 回目の例外発生時のスタック トレース

: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)

そして、それがメモリリークを引き起こします...

于 2013-01-10T22:01:42.643 に答える