Delphi XE3 Invalid Pointer при попытке освободить FSQL (TStringList)
Я создаю новое приложение в XE3, но использую некоторые устройства, созданные в D2007.
Я получаю сообщение об ошибке при освобождении элемента данных TStringList. Вот код, который создает элемент данных FSQL:
procedure TPayorDM.DataModuleCreate(Sender: TObject);
begin
FPayorDRM := TDRM.Create;
FSQL := TStringList.Create;
end;
Вот код, который получает ошибку:
procedure TPayorDM.DataModuleDestroy(Sender: TObject);
begin
FreeAndNil(FSQL);
if T_Payor.Active then T_Payor.Close;
FreeAndNil(FPayorDRM);
end;
Ошибка возникает в 'FreeAndNil(FSQL);'. Я пробовал 'FSQL.Free' и получаю тот же результат.
Вот ошибка, которую я получаю:
Проект: PayorUpdate.exe поднял класс исключения EInvalidPointer с сообщением "Операция недопустимого указателя.
Когда я ломаю синие стрелки (режим отладки) указывает на _FreeMem(Pointer(Self)); в процедуре TObject.FreeInstance в системном блоке выполните следующие действия:
procedure TObject.FreeInstance;
begin
CleanupInstance;
_FreeMem(Pointer(Self));
end;
Если я не освобожу элемент данных TStringList, у меня будет утечка памяти в приложении.
Есть ли возможность конфигурации, которую мне нужно установить? Я выполнил поиск в Google и не нашел ничего, что объясняет, что я делаю неправильно, кроме одной из трех возможностей:
- Он был выделен другим менеджером памяти.
- Он уже был освобожден однажды.
- Он никогда ничего не выделял.
Если я попытаюсь... кроме... Я могу обойти проблему, но я предпочитаю не делать этого.
Кстати, у меня есть другой TStringList в другом модуле, и я создаю и FreeAndNil, и я не получаю никакой ошибки.
Вот весь источник:
блок PayorDataMgr; интерфейс использует SysUtils, Classes, Dialogs, NativeXML, adscnnct, DB, adsdata, adsfunc, adstable, ace, cbs.drm, cbs.utils, cbs.LogFiles; const POLICY_TYPES: массив [1..3] из string = ("Первичный", "Вторичный", "Третичный"); Тип TPayorRecord = Запись ASSIGNBENEFITS: Boolean; АВТОРИЗАЦИЯ: логическое; BATCHBILL: логическое значение; CLAIMMAX: целое число; ПРОДОЛЖЕНИЕ: TDateTime; DISPENSEUPDATE: логическое значение; EHRSIGNOFF: логическое значение; EMCDEST: Строка; ФОРМА: Строка; GOVASSIGN: логическое значение; HIDE: Boolean; IGRPUNIQUE: целое число; LEGACYPLAN: Строка; LEGACYTYPE: String; LOCALATTN: Строка; МЕСТНОСТЬ: строка; МЕСТНОЕ ИМЯ: Строка; ЛОКАЛЬФОН: Строка; LOCALSTATE: String; LOCALSTREET: Строка; МЕСТНЫЙ ЗНАК: Строка; MASTERATTN: Строка; МАСТЕРСТВО: Строка; MASTERNAME: String; МАСТЕРФОН: Струна; MASTERSTATE: строка; MASTERSTREET: Строка; МАСТЕРЗИП: Струнный; MEDIGAPCODE: String; MEDIGAPPAYOR: Boolean; MEDPLANGUID: Строка; ИЗМЕНЕНО: TDateTime; NEICCODE: Строка; NEICTYPESTDC: целое число; ВЛАДЕЛЕЦ: Строка; PAYORGUID: Строка; PAYORSUBTYPESTDC: целое число; PAYORTYPESTDC: целое число; PAYORUNIQUE: целое число; PAYPERCENT: целое число; RTCODE: Строка; SRXPLANGUID: String; STATEFILTER: String; процедура Clear; Конец; TPayors = Запись закрытой функции _pGetCount: Integer; public Items: Массив TPayorRecord; процедура добавления (const aItem: TPayorRecord); функция CarriersList: TStrings; процедура бесплатная; function GetPayorGuid(const aPAYORUNIQUE:Integer):String; function IndexOfIgrpUnique(Const aIGRPUNIQUE:Integer):Integer; function IndexOfPayorUnique(Const aPAYORUNIQUE:Integer):Integer; процедура SortByName; Свойство Count:Integer Read _pGetCount; Конец; TPayorDM = класс (TDataModule) CommonConnection: TAdsConnection; T_Payor: TAdsTable; Q_Payor: TAdsQuery; процедура DataModuleDestroy (Отправитель: TObject); процедура DataModuleCreate (Отправитель: TObject); частный FPayorDRM: TDRM; FSQL: TStringList; function _LoadRecordFromTable:TPayorRecord; function _newIDSTRING(const aFormat:String='F'):String; Процедура {частные объявления} _pSetConnectionHandle(const Value: Integer); процедура _pSetErrorMessage(const Value: String); процедура _psetSQL(постоянное значение: TStringList); Свойство { Private properties } ErrorMessage:String Write _pSetErrorMessage; открытая функция AddPayor(var aPAYORRECORD:TPAYORRECORD):Boolean; функция ExecuteScript(const aTo,aFrom:string):Boolean; function FindPayor(const aPAYORGUID:String):Boolean; перегрузка; function FindPayor(const aPAYORUNIQUE:Integer):Boolean; перегрузка; function GetPayorData:TDRM; function GetRecordCount(const aData:String):Integer; функция LoadCarriers(const aHide:boolean = False):TPayors; функция LoadPayor: TPayorRecord; функция OpenTable:Boolean; function UpdateFromXML(const aPayorNode:TXMLNode): логический; Свойство {Публичные объявления} ConnectionHandle:Integer Write _pSetConnectionHandle; свойство DynamicPayorFields: TDRM Чтение FPayorDRM; свойство SQL: TStringList Чтение FSQL Запись _psetSQL; конец; вар PayorDM: TPayorDM; реализация {$R *.dfm} функции TPayorDM.AddPayor(var aPAYORRECORD: TPAYORRECORD): Boolean; begin Result:= False; если IsNull (aPAYORRECORD.LOCALNAME), то Exit; {Создать уникальные} {Добавить запись}, если не T_Payor.Active, то если не OpenTable, то Exit; с T_Payor попробуйте вставить; FieldByName('PAYORGUID').AsString:= _newIDSTRING; FieldByName('MASTERNAME').AsString:= aPAYORRECORD.MASTERNAME; FieldByName('MASTERSTREET').AsString:= aPAYORRECORD.MASTERSTREET; FieldByName('MASTERCITY').AsString:= aPAYORRECORD.MASTERCITY; FieldByName('MASTERSTATE').AsString:= aPAYORRECORD.MASTERSTATE; FieldByName('PAYORTYPESTDC').AsInteger:= aPAYORRECORD.PAYORTYPESTDC; FieldByName('MASTERZIP').AsString:= aPAYORRECORD.MASTERZIP; FieldByName('MASTERATTN').AsString:= aPAYORRECORD.MASTERATTN; FieldByName('MASTERPHONE').AsString:= aPAYORRECORD.MASTERPHONE; FieldByName('NEICCODE').AsString:= aPAYORRECORD.NEICCODE; FieldByName('RTCODE').AsString:= aPAYORRECORD.RTCODE; FieldByName('STATEFILTER').AsString:= aPAYORRECORD.STATEFILTER; FieldByName('NEICTYPESTDC').AsInteger:= aPAYORRECORD.NEICTYPESTDC; FieldByName('PAYORSUBTYPESTDC').AsInteger:= aPAYORRECORD.PAYORSUBTYPESTDC; FieldByName('OWNER').AsString:= aPAYORRECORD.OWNER; FieldByName('HIDE').AsBoolean:= aPAYORRECORD.HIDE; FieldByName('IGRPUNIQUE').AsInteger:= aPAYORRECORD.IGRPUNIQUE; FieldByName('FORM').AsString:= aPAYORRECORD.FORM; FieldByName('GOVASSIGN').AsBoolean:= aPAYORRECORD.GOVASSIGN; FieldByName('CLAIMMAX').AsInteger:= aPAYORRECORD.CLAIMMAX; FieldByName('MEDIGAPCODE').AsString:= aPAYORRECORD.MEDIGAPCODE; FieldByName('EMCDEST').AsString:= aPAYORRECORD.EMCDEST; FieldByName('ASSIGNBENEFITS').AsBoolean:= aPAYORRECORD.ASSIGNBENEFITS; FieldByName('BATCHBILL').AsBoolean:= aPAYORRECORD.BATCHBILL; FieldByName('MEDIGAPPAYOR').AsBoolean:= aPAYORRECORD.MEDIGAPPAYOR; FieldByName('MEDPLANGUID').AsString:= aPAYORRECORD.MEDPLANGUID; FieldByName('SRXPLANGUID').AsString:= aPAYORRECORD.SRXPLANGUID; FieldByName('PAYPERCENT').AsInteger:= aPAYORRECORD.PAYPERCENT; FieldByName('LOCALNAME').AsString:= aPAYORRECORD.LOCALNAME; FieldByName('LOCALSTREET').AsString:= aPAYORRECORD.LOCALSTREET; FieldByName('LOCALCITY').AsString:= aPAYORRECORD.LOCALCITY; FieldByName('LOCALSTATE').AsString:= aPAYORRECORD.LOCALSTATE; FieldByName('LOCALZIP').AsString:= aPAYORRECORD.LOCALZIP; FieldByName('LOCALATTN').AsString:= aPAYORRECORD.LOCALATTN; FieldByName('LOCALPHONE').AsString:= aPAYORRECORD.LOCALPHONE; FieldByName('EHRSIGNOFF').AsBoolean:= aPAYORRECORD.EHRSIGNOFF; FieldByName('DISCONTINUED').AsDateTime:= aPAYORRECORD.DISCONTINUED; FieldByName('MODIFIED').AsDateTime:= Сейчас; FieldByName('LEGACYPLAN').AsString:= aPAYORRECORD.LEGACYPLAN; FieldByName('LEGACYTYPE').AsString:= aPAYORRECORD.LEGACYTYPE; FieldByName('AUTHORIZE').AsBoolean:= aPAYORRECORD.AUTHORIZE; FieldByName('DISPENSEUPDATE').AsBoolean:= aPAYORRECORD.DISPENSEUPDATE; Сообщение; aPAYORRECORD.PAYORUNIQUE:= FieldByName('PAYORUNIQUE').AsInteger; aPAYORRECORD.PAYORGUID:= FieldByName('PAYORGUID').AsString; Близко; Результат: = Истина; за исключением E: EADSDatabaseError, действительно начинайте ErrorMessage:= 'AddPayor: ERRORCODE: ' + IntToStr(e.ACEErrorCode) + ' ERROR: ' + e.Message; конец; конец; конец; процедура TPayorDM.DataModuleCreate (Отправитель: TObject); начать FPayorDRM:= TDRM.Create; FSQL:= TStringList.Create; { FSQL Created } end; процедура TPayorDM.DataModuleDestroy (Отправитель: TObject); начать пробовать FSQL.Free; { FSQL Destroy - обойти, чтобы заставить модуль работать без ошибок}, кроме end; если T_Payor.Active, то T_Payor.Close; FreeAndNil (FPayorDRM); конец; function TPayorDM.ExecuteScript (const aTo, aFrom: string): Boolean; begin Result: = False; если FSQL.Count = 0, выход; с Q_Payor попробуйте если Active, то Close; SQL:= FSQL; ParamByName('to').Text:= aTo; ParambyName('from').Text:= aFrom; ExecSQL; если активен, то закрыть; Результат: = Истина; за исключением E: EADSDatabaseError, действительно начинайте ErrorMessage:= 'ExecuteScript: ERRORCODE: ' + IntToStr(e.ACEErrorCode) + ' ERROR: ' + e.Message + ' SQL: ' + Q_Payor.SQL.Text; конец; конец; конец; function TPayorDM.FindPayor(const aPAYORUNIQUE: Integer): Boolean; begin T_Payor.IndexName:= 'PAYORUNIQUE'; Результат:= T_Payor.FindKey([aPAYORUNIQUE]); конец; function TPayorDM.FindPayor(const aPAYORGUID: String): Boolean; begin T_Payor.IndexName:= 'PAYORGUID'; Результат:= T_Payor.FindKey([aPAYORGUID]); конец; function TPayorDM.GetPayorData: TDRM; начинать, если FPayorDRM.Count = 0, тогда FPayorDRM.BuildDRMList(T_Payor); Результат: = FPayorDRM; конец; function TPayorDM.GetRecordCount(const aData:string): целое число; начало Результат:= 0; если FSQL.Count = 0, выход; с Q_Payor попробуйте если Active, то Close; SQL:= FSQL; ParamByName('data').AsString:= aData; Открыто; Результат: = RecordCount; Близко; за исключением E: EADSDatabaseError, действительно начинайте ErrorMessage:= 'GetRecordCount: ERRORCODE: ' + IntToStr(e.ACEErrorCode) + ' ERROR: ' + e.Message; конец; конец; конец; Функция TPayorDM.LoadCarriers(const aHide: boolean): TPayors; начать OpenTable; Result.Free; с T_Payor начинайте сначала; хотя не EOF, начинайте, если T_Payor.FieldByName('HIDE').AsBoolean = aHide then Result.Add(_LoadRecordFromTable); Следующий; конец; Первый; Result.SortByName; конец; конец; функция TPayorDM.LoadPayor: TPayorRecord; начать Result.Clear; попробуйте если не T_Payor.active, тогда выходите; если T_Payor.RecNo = 0, тогда выход; Результат:= _LoadRecordFromTable; за исключением E: EADSDatabaseError, действительно начинайте ErrorMessage:= 'LoadPayor: ERRORCODE: ' + IntToStr(e.ACEErrorCode) + ' ERROR: ' + e.Message; конец; конец; конец; function TPayorDM.OpenTable: Boolean; begin Result:= False; с T_Payor попробуйте, если не активен, то Open; FPayorDRM.BuildDRMList(T_Payor); FPayorDRM.LoadValues (T_Payor); { test } FPayorDRM.ExportDRMList; { test } Результат: = True; за исключением E: EADSDatabaseError, действительно начинайте ErrorMessage:= 'OpenTable: ERRORCODE: ' + IntToStr(e.ACEErrorCode) + ' ERROR: ' + e.Message; конец; конец; конец; function TPayorDM.UpdateFromXML(const aPayorNode: TXMLNode): логический; var fKeyData:TXMLNode; IDX,fPAYORUNIQUE:Integer; begin Result:= False; если не назначено (aPayorNode), то Exit; попробуйте, если FPayorDRM.Count = 0, тогда FPayorDRM.BuildDRMList(T_Payor); FPayorDRM.ClearValues; fKeyData:= aPayorNode.FindNode('KeyData'); FPayorDRM.FindRecordFromKeyData(fKeyData,T_Payor); fPAYORUNIQUE:= FPayorDRM.FieldByName('PAYORUNIQUE').AsInteger; FPayorDRM.LoadValues (aPayorNode); если fPAYORUNIQUE = 0, тогда начинайте FPayorDRM.FieldByName('PAYORUNIQUE').AsInteger:= 0; FPayorDRM.FieldByName('PAYORGUID').AsString:= _newIDSTRING; FPayorDRM.FieldByName('MODIFIED').AsDate:= Now; FPayorDRM.AddRecord(T_Payor) и конец другого начала FPayorDRM.FieldByName('MODIFIED').AsDate:= Now; FPayorDRM.UpdateRecord(T_Payor); конец; кроме случаев e: исключение, начинайте ErrorMessage:= 'UpdateFromXML: ОШИБКА:' + e.Message; конец; конец; конец; function TPayorDM._LoadRecordFromTable: TPayorRecord; начинаются с T_Payor и начинаются Result.PAYORUNIQUE:= FieldByName('PAYORUNIQUE').AsInteger; Result.PAYORGUID:= FieldByName('PAYORGUID').AsString; Result.MASTERNAME:= FieldByName('MASTERNAME').AsString; Result.MASTERSTREET:= FieldByName('MASTERSTREET').AsString; Result.MASTERCITY:= FieldByName('MASTERCITY').AsString; Result.MASTERSTATE:= FieldByName('MASTERSTATE').AsString; Result.PAYORTYPESTDC:= FieldByName('PAYORTYPESTDC').AsInteger; Result.MASTERZIP:= FieldByName('MASTERZIP').AsString; Result.MASTERATTN:= FieldByName('MASTERATTN').AsString; Result.MASTERPHONE:= FieldByName('MASTERPHONE').AsString; Result.NEICCODE:= FieldByName('NEICCODE').AsString; Result.RTCODE:= FieldByName('RTCODE').AsString; Result.STATEFILTER:= FieldByName('STATEFILTER').AsString; Result.NEICTYPESTDC:= FieldByName('NEICTYPESTDC').AsInteger; Result.PAYORSUBTYPESTDC:= FieldByName('PAYORSUBTYPESTDC').AsInteger; Result.OWNER:= FieldByName('OWNER').AsString; Result.HIDE:= FieldByName('HIDE').AsBoolean; Result.IGRPUNIQUE:= FieldByName('IGRPUNIQUE').AsInteger; Result.FORM:= FieldByName('FORM').AsString; Result.GOVASSIGN:= FieldByName('GOVASSIGN').AsBoolean; Result.CLAIMMAX:= FieldByName('CLAIMMAX').AsInteger; Result.MEDIGAPCODE:= FieldByName('MEDIGAPCODE').AsString; Result.EMCDEST:= FieldByName('EMCDEST').AsString; Result.ASSIGNBENEFITS:= FieldByName('ASSIGNBENEFITS').AsBoolean; Result.BATCHBILL:= FieldByName('BATCHBILL').AsBoolean; Result.MEDIGAPPAYOR:= FieldByName('MEDIGAPPAYOR').AsBoolean; Result.MEDPLANGUID:= FieldByName('MEDPLANGUID').AsString; Result.SRXPLANGUID:= FieldByName('SRXPLANGUID').AsString; Result.PAYPERCENT:= FieldByName('PAYPERCENT').AsInteger; Result.LOCALNAME:= FieldByName('LOCALNAME').AsString; Result.LOCALSTREET:= FieldByName('LOCALSTREET').AsString; Result.LOCALCITY:= FieldByName('LOCALCITY').AsString; Result.LOCALSTATE:= FieldByName('LOCALSTATE').AsString; Result.LOCALZIP:= FieldByName('LOCALZIP').AsString; Result.LOCALATTN:= FieldByName('LOCALATTN').AsString; Result.LOCALPHONE:= FieldByName('LOCALPHONE').AsString; Result.EHRSIGNOFF:= FieldByName('EHRSIGNOFF').AsBoolean; Result.DISCONTINUED:= FieldByName('DISCONTINUED').AsDateTime; Result.MODIFIED:= FieldByName('MODIFIED').AsDateTime; Result.LEGACYPLAN:= FieldByName('LEGACYPLAN').AsString; Result.LEGACYTYPE:= FieldByName('LEGACYTYPE').AsString; Result.AUTHORIZE:= FieldByName('AUTHORIZE').AsBoolean; Result.DISPENSEUPDATE:= FieldByName('DISPENSEUPDATE').AsBoolean; конец; конец; function TPayorDM._newIDSTRING(const aFormat: String): String; begin Result:= ''; попробуй с Q_Payor сделай попробуй SQL.Clear; SQL.Add('ВЫБЕРИТЕ NEWIDSTRING( "' + aFormat + '") как GUID FROM system.iota'); Открыто; Результат:= FieldByName('GUID').AsString; Близко; кроме E: EADSDatabaseError, действительно начинайте ErrorMessage:= '_newIDSTRING: ERRORCODE: ' + IntToStr(e.ACEErrorCode) + ' ERROR: ' + e.Message; конец; конец; наконец-то конец; конец; процедура TPayorDM._pSetConnectionHandle(постоянное значение: целое число); начинать, если T_Payor.Active тогда T_Payor.Close; CommonConnection.SetHandle(значение); Открытый стол; конец; процедура TPayorDM._pSetErrorMessage(const Value: String); begin WriteError('[TPayorDM]' + Value,LogFilename); конец; процедура TPayorDM._psetSQL(постоянное значение: TStringList); начать FSQL: = значение; конец; { TPayorRecord } процедура TPayorRecord.Clear; начать PAYORUNIQUE:= 0; PAYORGUID:= ''; MASTERNAME:= ''; MASTERSTREET:= ''; МАСТЕРСТВО:= ''; MASTERSTATE:= ''; PAYORTYPESTDC:= 0; MASTERZIP:= ''; MASTERATTN:= ''; МАСТЕРФОН:= ''; NEICCODE:= ''; RTCODE:= ''; STATEFILTER:= ''; NEICTYPESTDC:= 0; PAYORSUBTYPESTDC:= 0; ВЛАДЕЛЕЦ:= ''; HIDE:= Ложь; IGRPUNIQUE:= 0; ФОРМА:= ''; GOVASSIGN:= Ложь; CLAIMMAX:= 0; MEDIGAPCODE:= ''; EMCDEST:= ''; НАЗНАЧЕНИЕ ПРЕИМУЩЕСТВ:= False; BATCHBILL:= Ложь; MEDIGAPPAYOR:= Ложь; MEDPLANGUID:= ''; SRXPLANGUID:= ''; PAYPERCENT:= 0; ЛОКАЛЬНОЕ ИМЯ: = ''; LOCALSTREET: = ''; МЕСТНОСТЬ:= ''; LOCALSTATE:= ''; LOCALZIP:= ''; LOCALATTN:= ''; ЛОКАЛЬФОН: = ''; EHRSIGNOFF: = Ложь; ПРОДОЛЖЕНИЕ:= 0; ИЗМЕНЕНО:= 0; LEGACYPLAN:= ''; LEGACYTYPE:= ''; РАЗРЕШИТЬ: = Ложь; DISPENSEUPDATE: = Ложь; конец; Процедура { TPayors } TPayors.Add(const aItem: TPayorRecord); begin SetLength(Items,Count + 1); Items[Count - 1]:= aItem; конец; функция TPayors.CarriersList: TStrings; var I: целое число; begin Result:= TStringList.Create; Result.Clear; Сортировать по имени; попробуйте для I:= 0 для подсчета - 1 для Result.Add(Items[I].LOCALNAME); наконец-то конец; конец; процедура TPayors.Free; начало элементов: = ноль; конец; function TPayors.GetPayorGuid(const aPAYORUNIQUE: Integer): String; var Idx:Integer; begin Result:= ''; Idx:= IndexOfPayorUnique(aPAYORUNIQUE); если нет (Idx = -1), то Результат:= Items[Idx].PAYORGUID; конец; функция TPayors.IndexOfIgrpUnique(const aIGRPUNIQUE: Integer): Integer; var I: целое число; начало Результат:= -1; для I:= 0 до счета - 1 делать, если элементы [I].IGRPUNIQUE = aIGRPUNIQUE затем начинаются Результат: = I; Перерыв; конец; конец; function TPayors.IndexOfPayorUnique(const aPAYORUNIQUE: Integer): Integer; var I: целое число; начало Результат:= -1; для I:= 0 для подсчета - 1 делать, если элементы [I].PAYORUNIQUE = aPAYORUNIQUE затем начинают Результат: = I; Перерыв; конец; конец; процедура TPayors.SortByName; var fSort:TStringList; fParse:TStrings; I,Idx: Integer; fTempPayor:TPayors; begin fSort:= TStringList.Create; fParse:= TStringList.Create; fTempPayor.Items:= Self.Items; fSort.Sorted:= True; попробуйте для I:= 0 для подсчета - 1 для fSort.Add(Items[I].LOCALNAME + #9 + IntToStr(I)); Предметы: = ноль; для I: от = 0 до fSort.Count - 1 начинается cbs.utils.ParseDelimited(fParse,fSort[I],#9); Idx:= StrToInt(fParse[1]); Добавить (fTempPayor.Items[IDX]); конец; наконец, fTempPayor.Free; fParse.Free; fSort.Free; конец; конец; function TPayors._pGetCount: Integer; начало Результат: = длина (элементы); конец; конец.
1 ответ
Вы (скорее всего) дважды освобождаете список строк (и никогда не освобождаете хотя бы один). Проблема в установщике вашего свойства 'SQL' (которое поддерживается полем 'FSQL'):
procedure TPayorDM._psetSQL(const Value: TStringList);
begin
FSQL := Value;
end;
Здесь вы теряете ссылку на уже существующий список строк (LHS). Рассмотрим следующий сценарий:
Ты звонишь
PayorDM.SQL := AStringList;
и ссылка на приватное поле, созданное вами в конструкторе, пропала, вместо этого вы сохраняете ссылку на 'AStringList'. После этого в какой-то момент вы уничтожаете 'AStringList', теперь поле 'FSQL' является устаревшим указателем. Когда в деструкторе вы звоните
FSQL.Free;
Вы получаете недопустимую операцию указателя.
Измените свой сеттер на:
procedure TPayorDM._psetSQL(const Value: TStringList);
begin
FSQL.Assign(Value);
end;