我正在 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:整数; 开始 结果:=长度(项目); 结尾; 结尾。