delphi – 当我重新排列TObjectList时,为什么会出现“无效指针操
发布时间:2020-12-15 09:25:42 所属栏目:大数据 来源:网络整理
导读:我们假设我有以下自定义列表,其中包含以下声明: type TCustomList = class(TObjectList) private function GetItem(AIndex: Integer): TMyObject; // virtual; procedure SetItem(Index: Integer; AObject: TMyObject);... public property Items[Index: In
我们假设我有以下自定义列表,其中包含以下声明:
type TCustomList = class(TObjectList) private function GetItem(AIndex: Integer): TMyObject; // virtual; procedure SetItem(Index: Integer; AObject: TMyObject); ... public property Items[Index: Integer]: TMyObject read GetItem write SetItem; procedure InsertSort(); end; 通过以下实现: implementation function TCustomList.GetItem(AIndex: Integer): TMyObject; begin Result := TMyObject(inherited Items[AIndex]); end; procedure TCustomList.SetItem(Index: Integer; AObject: TMyObject); begin inherited Items[Index]:= AObject; end; procedure TCustomList.InsertSort; var i,j: integer; key: TMyObject; begin for j := 1 to self.Count - 1 do begin key:= self.Items[j]; i := j - 1; while ((i >= 0) AND (self.Items[i].Compare(key)>0)) do begin self.Items[i+1]:= self.Items[i]; // does not WORK!!! properly.. System.Contnrs problem ?? i := i-1; end; // while self.Items[i+1]:= key; end; // for end; // procedure InsertSort 当我在TMyObject的一组实例上运行代码时,我得到一个无效的指针操作异常.我认为,这是由于通过Items属性读取和写入TCustomList的元素造成的. 为什么会出现这个无效指针操作异常? 解决方法
这里发生的事情是对象列表的所有权正在阻碍.因为您正在使用TObjectList,所以只要要求列表忘记某个成员,它就会销毁它.当您编写代码时会发生这种情况:
self.Items[i+1] := ... 在分配之前存储在索引i 1处的成员将被销毁,以便为新项目腾出空间.最终,您将最终销毁已经被销毁的对象,并且当您的无效指针异常发生时. 要解决此问题,可以使用Extract方法,该方法允许您在不破坏项目的情况下删除项目.或者@Arioch在评论中巧妙地指出,Exchange方法非常适合比较. 更容易的是在排序期间暂时将OwnsObjects切换为False,而不是忘记在完成后将其恢复.或许你甚至不想使用OwnsObjects = True.在那种情况下,你想要TList. 坦率地说,尽管你最好使用最初由TList公开的内置Sort方法.你根本没有必要在已经有一个非常体面的类上实现一个排序方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |