我正在 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)); 在 System 单元中的过程 TObject.FreeInstance 中如下:
procedure TObject.FreeInstance;
begin
CleanupInstance;
_FreeMem(Pointer(Self));
end;
如果我不释放 TStringList 数据项,我会在应用程序中出现内存泄漏。
我可能需要设置一个配置选项吗?我用谷歌搜索,除了以下三种可能性之一之外,没有找到任何解释我做错了什么的东西:
- 它是由其他一些内存管理器分配的。
- 它之前已经被释放过一次。
- 它从来没有被任何东西分配过。
如果我尝试...除了...我能够解决这个问题,但我不想这样做。
顺便说一句,我在不同的单元中有另一个 TStringList 并且我创建了 FreeAndNil 并且我没有收到任何错误。
这是完整的来源:
单位 PayorDataMgr;
界面
用途
系统工具,
类,
对话框,
本机XML,
广告,
D B,
广告数据,
广告功能,
可调整的,
高手,
cbs.drm,
cbs.utils,
cbs.LogFiles;
常量
POLICY_TYPES: array[1..3] of string = ('Primary','Secondary','Tertiary');
类型
TPayorRecord = 记录
分配好处:布尔值;
授权:布尔值;
BATCHBILL:布尔值;
CLAIMMAX:整数;
停产:TDateTime;
分配更新:布尔值;
EHRSIGNOFF:布尔值;
EMCDEST:字符串;
形式:字符串;
GOVASSIGN:布尔值;
隐藏:布尔值;
IGRPUNIQUE:整数;
LEGACYPLAN:字符串;
LEGACYTYPE:字符串;
本地:字符串;
地点:字符串;
本地名称:字符串;
本地电话:字符串;
本地状态:字符串;
本地街道:字符串;
本地邮编:字符串;
MASTEATTN:字符串;
掌握:字符串;
MASTERNAME:字符串;
主机:字符串;
主控:字符串;
MASTERSTREET:字符串;
MASTERZIP:字符串;
MEDIGAPCODE:字符串;
MEDIGAPPAYOR:布尔值;
MEDPLANGUID:字符串;
修改:TDateTime;
NEICCODE:字符串;
NEICTYPESTDC:整数;
所有者:字符串;
PAYORGUID:字符串;
PAYORSUBTYPESTDC:整数;
PAYORTYPESTDC:整数;
PAYORUNIQUE:整数;
支付百分比:整数;
RTCODE:字符串;
SRXPLANGUID:字符串;
状态过滤器:字符串;
程序清除;
结尾;
TPayors = 记录
私人的
函数_pGetCount:整数;
上市
项目:TPayorRecord 数组;
程序添加(常量 aItem:TPayorRecord);
功能运营商列表:TStrings;
程序免费;
函数 GetPayorGuid(const aPAYORUNIQUE:Integer):String;
函数 IndexOfIgrpUnique(Const aIGRPUNIQUE:Integer):Integer;
函数 IndexOfPayorUnique(Const aPAYORUNIQUE:Integer):Integer;
程序排序名称;
属性计数:整数读取_pGetCount;
结尾;
TPayorDM = 类(TDataModule)
公共连接:TAdsConnection;
T_Payor:TAdsTable;
Q_Payor:TAdsQuery;
过程 DataModuleDestroy(发件人:TObject);
过程 DataModuleCreate(Sender: TObject);
私人的
FPayorDRM:TDRM;
FSQL:TStringList;
函数_LoadRecordFromTable:TPayorRecord;
函数 _newIDSTRING(const aFormat:String='F'):String;
{ 私有声明 }
过程_pSetConnectionHandle(常量值:整数);
过程_pSetErrorMessage(常量值:字符串);
过程_psetSQL(常量值:TStringList);
{私有属性}
属性错误消息:字符串写入_pSetErrorMessage;
上市
函数 AddPayor(var aPAYORRECORD:TPAYORRECORD):Boolean;
函数 ExecuteScript(const aTo,aFrom:string):Boolean;
函数 FindPayor(const aPAYORGUID:String):Boolean;overload;
函数 FindPayor(const aPAYORUNIQUE:Integer):Boolean;overload;
函数GetPayorData:TDRM;
函数 GetRecordCount(const aData:String):Integer;
函数 LoadCarriers(const aHide:boolean = False):TPayors;
函数 LoadPayor:TPayorRecord;
函数 OpenTable:Boolean;
函数 UpdateFromXML(const aPayorNode:TXMLNode):boolean;
{ 公开声明 }
属性ConnectionHandle:整数写入_pSetConnectionHandle;
属性 DynamicPayorFields:TDRM 读取 FPayorDRM;
属性 SQL:TStringList 读取 FSQL 写入 _psetSQL;
结尾;
变量
付款人DM:TPayorDM;
执行
{$R *.dfm}
函数 TPayorDM.AddPayor(var aPAYORRECORD: TPAYORRECORD): 布尔值;
开始
结果:=错误;
如果 IsNull(aPAYORRECORD.LOCALNAME) 则退出;
{ 创建唯一性 }
{ 添加记录 }
如果不是 T_Payor.Active 那么
如果不是 OpenTable 则退出;
用 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) +
' 错误:' + e.Message;
结尾;
结尾;
结尾;
过程 TPayorDM.DataModuleCreate(Sender: TObject);
开始
FPayorDRM := TDRM.创建;
FSQL := TStringList.创建;{ FSQL 创建 }
结尾;
过程 TPayorDM.DataModuleDestroy(Sender: TObject);
开始
尝试
FSQL.免费;{ FSQL 被破坏 - 解决方法以使单元无错误地运行}
除了
结尾;
如果 T_Payor.Active 那么 T_Payor.Close;
FreeAndNil(FPayorDRM);
结尾;
函数 TPayorDM.ExecuteScript(const aTo, aFrom: string):Boolean;
开始
结果:=错误;
如果 FSQL.Count = 0 则退出;
用 Q_Payor 做
尝试
如果活动则关闭;
SQL := FSQL;
ParamByName('to').Text := aTo;
ParambyName('from').Text := aFrom;
执行SQL;
如果活动则关闭;
结果:=真;
除了 E: EADSDatabaseError 做
开始
ErrorMessage := 'ExecuteScript: ERRORCODE: ' + IntToStr(e.ACEErrorCode) +
' 错误:' + e.Message + ' SQL:' + Q_Payor.SQL.Text;
结尾;
结尾;
结尾;
函数 TPayorDM.FindPayor(const aPAYORUNIQUE: Integer): Boolean;
开始
T_Payor.IndexName := 'PAYORUNIQUE';
结果:= T_Payor.FindKey([aPAYORUNIQUE]);
结尾;
函数 TPayorDM.FindPayor(const aPAYORGUID: String): 布尔值;
开始
T_Payor.IndexName := 'PAYORGUID';
结果:= T_Payor.FindKey([aPAYORGUID]);
结尾;
函数 TPayorDM.GetPayorData:TDRM;
开始
如果 FPayorDRM.Count = 0 那么
FPayorDRM.BuildDRMList(T_Payor);
结果:= FPayorDRM;
结尾;
函数 TPayorDM.GetRecordCount(const aData:string): 整数;
开始
结果:= 0;
如果 FSQL.Count = 0 则退出;
用 Q_Payor 做
尝试
如果活动则关闭;
SQL := FSQL;
ParamByName('data').AsString := aData;
打开;
结果:=记录计数;
关;
除了 E: EADSDatabaseError 做
开始
ErrorMessage := 'GetRecordCount: ERRORCODE: ' + IntToStr(e.ACEErrorCode) +
' 错误:' + e.Message;
结尾;
结尾;
结尾;
函数 TPayorDM.LoadCarriers(const aHide: boolean): TPayors;
开始
打开表;
结果.免费;
用 T_Payor 做
开始
第一的;
虽然不是 EOF 做
开始
如果 T_Payor.FieldByName('HIDE').AsBoolean = aHide 然后
Result.Add(_LoadRecordFromTable);
下一个;
结尾;
第一的;
结果.按名称排序;
结尾;
结尾;
函数 TPayorDM.LoadPayor: TPayorRecord;
开始
结果。清除;
尝试
如果不是 T_Payor.active 则退出;
如果 T_Payor.RecNo = 0 则退出;
结果:= _LoadRecordFromTable;
除了 E: EADSDatabaseError 做
开始
ErrorMessage := 'LoadPayor: ERRORCODE: ' + IntToStr(e.ACEErrorCode) +
' 错误:' + e.Message;
结尾;
结尾;
结尾;
函数 TPayorDM.OpenTable:布尔值;
开始
结果:=错误;
用 T_Payor 做
尝试
如果不活动则打开;
FPayorDRM.BuildDRMList(T_Payor);
FPayorDRM.LoadValues(T_Payor); { 测试 }
FPayorDRM.ExportDRMList;{ 测试 }
结果:=真;
除了 E: EADSDatabaseError 做
开始
ErrorMessage := 'OpenTable: ERRORCODE: ' + IntToStr(e.ACEErrorCode) +
' 错误:' + e.Message;
结尾;
结尾;
结尾;
函数 TPayorDM.UpdateFromXML(const aPayorNode: TXMLNode): boolean;
变量
fKeyData:TXMLNode;
Idx,fPAYORUNIQUE:整数;
开始
结果:=错误;
如果未分配(aPayorNode)则退出;
尝试
如果 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 := 现在;
FPayorDRM.AddRecord(T_Payor)
结尾
别的
开始
FPayorDRM.FieldByName('MODIFIED').AsDate := 现在;
FPayorDRM.UpdateRecord(T_Payor);
结尾;
除了 e:exception do
开始
ErrorMessage := 'UpdateFromXML: ERROR: ' + e.Message;
结尾;
结尾;
结尾;
函数 TPayorDM._LoadRecordFromTable: TPayorRecord;
开始
用 T_Payor 做
开始
结果.PAYORUNIQUE := FieldByName('PAYORUNIQUE').AsInteger;
结果.PAYORGUID := FieldByName('PAYORGUID').AsString;
结果.MASTERNAME := FieldByName('MASTERNAME').AsString;
结果.MASTERSTREET := FieldByName('MASTERSTREET').AsString;
结果.MASTERCITY := FieldByName('MASTERCITY').AsString;
结果.MASTERSTATE := FieldByName('MASTERSTATE').AsString;
结果.PAYORTYPESTDC := FieldByName('PAYORTYPESTDC').AsInteger;
结果.MASTERZIP := FieldByName('MASTERZIP').AsString;
结果.MASTERATTN := FieldByName('MASTERATTN').AsString;
结果.MASTERPHONE := FieldByName('MASTERPHONE').AsString;
结果.NEICCODE := FieldByName('NEICCODE').AsString;
结果.RTCODE := FieldByName('RTCODE').AsString;
结果.STATEFILTER := FieldByName('STATEFILTER').AsString;
结果.NEICTYPESTDC := FieldByName('NEICTYPESTDC').AsInteger;
结果.PAYORSUBTYPESTDC := FieldByName('PAYORSUBTYPESTDC').AsInteger;
结果.OWNER := FieldByName('OWNER').AsString;
结果.HIDE := FieldByName('HIDE').AsBoolean;
结果.IGRPUNIQUE := FieldByName('IGRPUNIQUE').AsInteger;
结果.FORM := FieldByName('FORM').AsString;
结果.GOVASSIGN := FieldByName('GOVASSIGN').AsBoolean;
结果.CLAIMMAX := FieldByName('CLAIMMAX').AsInteger;
结果.MEDIGAPCODE := FieldByName('MEDIGAPCODE').AsString;
结果.EMCDEST := FieldByName('EMCDEST').AsString;
Result.ASSIGNBENEFITS := FieldByName('ASSIGNBENEFITS').AsBoolean;
结果.BATCHBILL := FieldByName('BATCHBILL').AsBoolean;
结果.MEDIGAPPAYOR := FieldByName('MEDIGAPPAYOR').AsBoolean;
结果.MEDPLANGUID := FieldByName('MEDPLANGUID').AsString;
结果.SRXPLANGUID := FieldByName('SRXPLANGUID').AsString;
结果.PAYPERCENT := FieldByName('PAYPERCENT').AsInteger;
Result.LOCALNAME := FieldByName('LOCALNAME').AsString;
结果.LOCALSTREET := FieldByName('LOCALSTREET').AsString;
结果.LOCALCITY := FieldByName('LOCALCITY').AsString;
结果.LOCALSTATE := FieldByName('LOCALSTATE').AsString;
结果.LOCALZIP := FieldByName('LOCALZIP').AsString;
结果.LOCALATTN := FieldByName('LOCALATTN').AsString;
结果.LOCALPHONE := FieldByName('LOCALPHONE').AsString;
结果.EHRSIGNOFF := FieldByName('EHRSIGNOFF').AsBoolean;
结果.DISCONTINUED := FieldByName('DISCONTINUED').AsDateTime;
结果.MODIFIED := FieldByName('MODIFIED').AsDateTime;
结果.LEGACYPLAN := FieldByName('LEGACYPLAN').AsString;
结果.LEGACYTYPE := FieldByName('LEGACYTYPE').AsString;
结果.AUTHORIZE := FieldByName('AUTHORIZE').AsBoolean;
结果.DISPENSEUPDATE := FieldByName('DISPENSEUPDATE').AsBoolean;
结尾;
结尾;
函数 TPayorDM._newIDSTRING(const aFormat: String): String;
开始
结果 := '';
尝试
用 Q_Payor 做
尝试
SQL.清除;
SQL.Add('SELECT NEWIDSTRING("' + aFormat + '" ) AS GUID FROM system.iota');
打开;
结果:= FieldByName('GUID').AsString;
关;
除了 E: EADSDatabaseError 做
开始
ErrorMessage := '_newIDSTRING: ERRORCODE: ' + IntToStr(e.ACEErrorCode) +
' 错误:' + e.Message;
结尾;
结尾;
最后
结尾;
结尾;
过程 TPayorDM._pSetConnectionHandle(const Value: Integer);
开始
如果 T_Payor.Active 那么 T_Payor.Close;
CommonConnection.SetHandle(Value);
打开表;
结尾;
过程 TPayorDM._pSetErrorMessage(const Value: String);
开始
WriteError('[TPayorDM]' + Value,LogFilename);
结尾;
过程 TPayorDM._psetSQL(const Value: TStringList);
开始
FSQL := 值;
结尾;
{ TPayorRecord }
程序 TPayorRecord.Clear;
开始
PAYORUNIQUE := 0;
PAYORGUID := '';
MASTERNAME := '';
MASTERSTREET := '';
掌握:= '';
主控:= '';
PAYORTYPESTDC := 0;
MASTERZIP := '';
MASTEATTN := '';
主机 := '';
NEICCODE := '';
RTCODE := '';
状态过滤器 := '';
NEICTYPESTDC := 0;
PAYORSUBTYPESTDC := 0;
所有者:='';
隐藏:=假;
IGRPUNIQUE := 0;
表格 := '';
GOVASSIGN := 错误;
索赔最大值:= 0;
MEDIGAPCODE := '';
EMCDEST := '';
分配好处:= 假;
批处理:= 假;
MEDIGAPPAYOR := 错误;
MEDPLANGUID := '';
SRXPLANGUID := '';
支付百分比:= 0;
本地名称 := '';
本地街 := '';
地点 := '';
本地状态:= '';
本地邮编:= '';
LOCALATTN := '';
本地电话 := '';
EHRSIGNOFF := 错误;
停产:= 0;
修改:= 0;
LEGACYPLAN := '';
LEGACYTYPE := '';
授权:=错误;
分配更新:=错误;
结尾;
{ TPayors }
过程 TPayors.Add(const aItem: TPayorRecord);
开始
SetLength(Items,Count + 1);
项目[计数 - 1] := aItem;
结尾;
函数 TPayors.CarriersList:TStrings;
变量
一:整数;
开始
结果:= TStringList.Create;
结果。清除;
按名称分类;
尝试
对于 I := 0 to Count - 1 do
Result.Add(Items[I].LOCALNAME);
最后
结尾;
结尾;
程序 TPayors.Free;
开始
项目:= 无;
结尾;
函数 TPayors.GetPayorGuid(const aPAYORUNIQUE: Integer): String;
变量
idx:整数;
开始
结果 := '';
Idx := IndexOfPayorUnique(aPAYORUNIQUE);
如果不是 (Idx = -1) 那么
结果 := Items[Idx].PAYORGUID;
结尾;
函数 TPayors.IndexOfIgrpUnique(const aIGRPUNIQUE: Integer): Integer;
变量
一:整数;
开始
结果:= -1;
对于 I := 0 to Count - 1 do
如果 Items[I].IGRPUNIQUE = aIGRPUNIQUE 然后
开始
结果:=我;
休息;
结尾;
结尾;
函数 TPayors.IndexOfPayorUnique(const aPAYORUNIQUE: Integer): Integer;
变量
一:整数;
开始
结果:= -1;
对于 I := 0 to Count - 1 do
如果 Items[I].PAYORUNIQUE = aPAYORUNIQUE 那么
开始
结果:=我;
休息;
结尾;
结尾;
程序 TPayors.SortByName;
变量
fSort:TStringList;
fParse:TStrings;
I,Idx:整数;
fTempPayor:TPayors;
开始
fSort := TStringList.Create;
fParse := TStringList.Create;
fTempPayor.Items := Self.Items;
fSort.Sorted := 真;
尝试
对于 I := 0 to Count - 1 do
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.免费;
fSort.免费;
结尾;
结尾;
函数 TPayors._pGetCount:整数;
开始
结果:=长度(项目);
结尾;
结尾。