function TFDDatSRow.SetRowError(const AValue: EFDException): Boolean;
var
pInfo: PFDDataRowExtraInfo;
begin
Result := False;
pInfo := GetRowInfo(AValue <> nil);
if pInfo <> nil then begin
if pInfo^.FRowException <> nil then begin
Result := True;
FDFreeAndNil(pInfo^.FRowException);
end;
if AValue <> nil then
AValue.Duplicate(pInfo^.FRowException)
else
CheckNoInfo;
end;
end;
Но на выходе - утечка памяти.
Если впучную освобождаю
FreeAndNil(FTab.Rows[0].RowError);
, то AV (получаетсяу уже освобожден ресурс).
Единственный рабочий вариант, который прищел в голову - создавать исключение, пихать ссылку на него в свою переменную и потом освобождать эту мою переменную - нет ни AV, ни утечки памяти.
НО почему так сложно? По какой причине не работает прямо вот так.
Вопрос
Vitaly X
Тривиальная проблема, но не могу понять почему
Есть стандартный пример из Delphi
unit fCreateRows; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, ComCtrls, ExtCtrls, StdCtrls, Buttons, FireDAC.DatS, FireDAC.Stan.Intf, FireDAC.Stan.Error; type TfrmCreateRows = class(TForm) btnCreateTable: TButton; btnPopulate: TButton; btnPrint: TButton; btnAddError: TButton; pnlControlButtons: TPanel; Console: TMemo; pnlMain: TPanel; procedure FormDestroy(Sender: TObject); procedure btnCreateTableClick(Sender: TObject); procedure btnPopulateClick(Sender: TObject); procedure btnPrintClick(Sender: TObject); procedure btnAddErrorClick(Sender: TObject); private { Private declarations } FTab: TFDDatSTable; public { Public declarations } end; var frmCreateRows: TfrmCreateRows; implementation uses uDatSUtils; {$R *.dfm} procedure TfrmCreateRows.btnCreateTableClick(Sender: TObject); begin FTab := TFDDatSTable.Create('Table'); // define table structure FTab.Columns.Add('id', dtInt32); FTab.Columns.Add('string', dtAnsiString).Size := 12; FTab.Columns.Add('double', dtDouble); btnPopulate.Enabled := True; end; procedure TfrmCreateRows.btnPopulateClick(Sender: TObject); var oCol: TFDDatSColumn; oRow1, oRow2: TFDDatSRow; begin // 1. create row oRow1 := FTab.NewRow; // set values oRow1.SetValues([1, 'first row', 14.124145]); // add to table FTab.Rows.Add(oRow1); // 2. create and set values oRow2 := FTab.NewRow([2, 'second row', 14515.1251]); // add to table FTab.Rows.Add(oRow2); // 3. create, set values and add to table FTab.Rows.Add([3, 'third row', 114.22]); // 4. edit row oRow1.BeginEdit; oRow1.SetData(0, 10); oRow1.EndEdit; // 5. once more oCol := FTab.Columns[1]; oRow1.BeginEdit; oRow1.SetData(oCol, 'ten row'); oRow1.EndEdit; btnAddError.Enabled := True; btnPrint.Enabled := True; end; procedure TfrmCreateRows.btnAddErrorClick(Sender: TObject); begin FTab.Rows[0].RowError := EFDException.Create('Jaaaaa'); btnPrint.Enabled := True; end; procedure TfrmCreateRows.btnPrintClick(Sender: TObject); begin PrintRows(FTab, Console.Lines, 'Our rows...'); end; procedure TfrmCreateRows.FormDestroy(Sender: TObject); begin FTab.Free; end; end.По самому примеру как бы вопросов нет, работает как надо. Но если я создаю исключение
FTab.Rows[0].RowError := EFDException.Create('Jaaaaa');, то потом не понятно как его убить.
Смотрел в debug, вроде убивается тут
function TFDDatSRow.SetRowError(const AValue: EFDException): Boolean; var pInfo: PFDDataRowExtraInfo; begin Result := False; pInfo := GetRowInfo(AValue <> nil); if pInfo <> nil then begin if pInfo^.FRowException <> nil then begin Result := True; FDFreeAndNil(pInfo^.FRowException); end; if AValue <> nil then AValue.Duplicate(pInfo^.FRowException) else CheckNoInfo; end; end;Но на выходе - утечка памяти.
Если впучную освобождаю
FreeAndNil(FTab.Rows[0].RowError);, то AV (получаетсяу уже освобожден ресурс).
Единственный рабочий вариант, который прищел в голову - создавать исключение, пихать ссылку на него в свою переменную и потом освобождать эту мою переменную - нет ни AV, ни утечки памяти.
НО почему так сложно? По какой причине не работает прямо вот так.
Спасибо
0 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.