Bof*_*ofA 38 delphi generics tlist delphi-xe8
升级到XE8后,我们的一些项目开始破坏数据.看起来像TList实现中的一个错误.
program XE8Bug1;
{$APPTYPE CONSOLE}
uses
System.SysUtils, Generics.Collections;
type
TRecord = record
A: Integer;
B: Int64;
end;
var
FRecord: TRecord;
FList: TList<TRecord>;
begin
FList := TList<TRecord>.Create;
FRecord.A := 1;
FList.Insert(0, FRecord);
FRecord.A := 3;
FList.Insert(1, FRecord);
FRecord.A := 2;
FList.Insert(1, FRecord);
Writeln(IntToStr(FList[0].A) + IntToStr(FList[1].A) + IntToStr(FList[2].A));
end.
Run Code Online (Sandbox Code Playgroud)
此代码在XE7和之前(应该是)打印"123",但在XE8中打印"120".也许有人知道这个的quickfix?
更新:非正式修复在这里
Bof*_*ofA 32
我发现现在TList<T>.Insert方法调用TListHelper.InternalInsertX取决于数据大小,在我的情况下:
procedure TListHelper.InternalInsertN(AIndex: Integer; const Value);
var
ElemSize: Integer;
begin
CheckInsertRange(AIndex);
InternalGrowCheck(FCount + 1);
ElemSize := ElSize;
if AIndex <> FCount then
Move(PByte(FItems^)[AIndex * ElemSize], PByte(FItems^)[(AIndex * ElemSize) + 1], (FCount - AIndex) * ElemSize);
Move(Value, PByte(FItems^)[AIndex * ElemSize], ElemSize);
Inc(FCount);
FNotify(Value, cnAdded);
end;
Run Code Online (Sandbox Code Playgroud)
我在第一次Move通话中看到了问题.目的地应该是:
PByte(FItems^)[(AIndex + 1) * ElemSize]
Run Code Online (Sandbox Code Playgroud)
不
PByte(FItems^)[(AIndex * ElemSize) + 1]
Run Code Online (Sandbox Code Playgroud)
Aaargh!
最后,我在我的项目中使用了Delphi XE7中的System.Generics.Defaults.pas和System.Generics.Collections.pas单元,现在所有工作都按预期工作.
更新:正如我所见,RTL没有受到影响,因为它不适TList<T>.Insert用于T大小> 8(或者我可能会错过什么?)
| 归档时间: |
|
| 查看次数: |
3676 次 |
| 最近记录: |