请教Delphi2010 TStringlist的问题。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请教Delphi2010 TStringlist的问题。相关的知识,希望对你有一定的参考价值。

我定义了一个TStringList的变量,打算用来分割字符串,可是总是出错,单步执行时发现一运行到TextList.Create这句时,它就自动回到了程序的最开头,本来我是想直接把数据读入数组的,但是无论怎么读都出错,望各位哥哥姐姐不吝赐教。
unit 设置透明度;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm2 = class(TForm)
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
private
Private declarations
public
Public declarations
end;

var
Form2: TForm2;

implementation

$R *.dfm

procedure TForm2.FormCreate(Sender: TObject);
Var
i,j:Integer;
t:TextFile;
a:array[1..4,1..100]of string;
TextList:TStringList;
s:string;
begin
AssignFile(t,'D:\仓库.in');
Reset(t);
while Not(Eof(t)) do
Begin
Inc(i);
Readln(t,s);
TextList.Create;
TextList.DeliMiter:='/';
TextList.DelimitedText := s;
a[i,1]:=TextList.Strings[0];
a[i,2]:=TextList.Strings[1];
a[i,3]:=TextList.Strings[2];
TextList.Free;
End;
CloseFile(t);
For j:=1 to i do
Begin
ListBox1.Items.Add(a[i,2]);
End;
end;

end.

参考技术A 一楼解释TStringList的实例构建已经很清楚了,不过发现程序还有别的问题:
1、变量i没有赋予初值,编译时会有警告,不应该忽略它
2、TextList的创建和销毁都不应该在while循环里面,应该外置,对属性DeliMiter的赋值也可以外置追问

1.好像没有弹出警告,不过我也会接受你的建议,谢谢~
2.TextList我是用来分隔字符串的,但是如果外置的话,那不就增加了两倍的时间复杂度?

参考技术B TextList:=Tstringlist.Create; //创建应该这样写!
并非是TextList.Create;本回答被提问者采纳
参考技术C 保存。
或者直接用TFileStream读写文件。
或者尝试下TStringStream试试看。

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

【中文标题】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。谢谢。太棒了。在这可能是我的几个应用程序的问题之前,我遇到过这个问题。这很完美。再次感谢。丰富

以上是关于请教Delphi2010 TStringlist的问题。的主要内容,如果未能解决你的问题,请参考以下文章

Delphi:即使设置了 Delimiter,StringList Delimiter 也始终是空格字符

Delphi TStringList的用法

Delphi TStringList的用法

delphi TStringList 用法详解

delphi TStringList 用法详解

Delphi - TStringList 用法详解