Delphi XE3 尝试释放 FSQL (TStringList) 时指针无效

Posted

技术标签:

【中文标题】Delphi XE3 尝试释放 FSQL (TStringList) 时指针无效【英文标题】:Delphi XE3 Invalid Pointer when trying to free FSQL (TStringList) 【发布时间】:2014-09-08 21:30:30 【问题描述】:

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

【问题讨论】:

错误不在您显示的代码中 @Mason 还有另一个与键盘挂钩相关的问题... @JerryDodge 键盘钩子不一定是邪恶的。在那个特定的案例中,Rich 错误地认为需要一个键盘挂钩来处理他自己的应用程序中的输入事件。这里没有恶意软件的迹象,我认为响应 Rich 问题的 cmets 已经不合时宜了。 @Rich 我相信您的问题是有效的,但您的问题目前无法回答。正如我在第一条评论中所说,错误不在您显示的代码中。您需要向我们提供足够的详细信息才能诊断问题。显然,创建一个对象然后销毁它是正常的。一定是有别的东西在干扰。 我想我不应该提到使用 FreeAndNil 的问题。 【参考方案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;

【讨论】:

Sertac。谢谢。太棒了。在这可能是我的几个应用程序的问题之前,我遇到过这个问题。这很完美。再次感谢。丰富

以上是关于Delphi XE3 尝试释放 FSQL (TStringList) 时指针无效的主要内容,如果未能解决你的问题,请参考以下文章

把exe嵌入到自己的exe中。delphi xe3

Delphi XE3 Ctrl+Z 也可以撤消插入符号的移动

Delphi XE3 - Reuse socket rsTrue 在任何情况下都会被系统覆盖吗?

Delphi - 检查内存是不是“按时”释放

在delphi中XLSReadWriteII.组件的应用实例

delphi cxgrid里面的虚拟字段的checkbox可以多选并抓取选定的数据字段