0

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

    结尾。

4

1 回答 1

6

您(很可能)双重释放了一个字符串列表(并且从不释放至少一个)。问题出在“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;
于 2014-07-21T18:25:48.753 回答