4

.NetからDelphi7に移植されたTStringBuilderクラスを使用しています。

そして、これが私のコードスニペットです:

procedure TForm1.btn1Click(Sender: TObject);
const
  FILE_NAME = 'PATH TO A TEXT FILE';
var
  sBuilder: TStringBuilder;
  I: Integer;
  fil: TStringList;
  sResult: string;
  randInt: Integer;
begin
  randomize;
  sResult := '';
  for I := 1 to 100 do
  begin
    fil := TStringList.Create;
    try
      fil.LoadFromFile(FILE_NAME);

      randInt := Random(1024);

      sBuilder := TStringBuilder.Create(randInt);
      try
        sBuilder.Append(fil.Text);
        sResult := sBuilder.AsString;
      finally
        sBuilder.free;
      end;

      mmo1.Text := sResult;
    finally
      FreeAndNil(fil);
    end;
  end;
  showmessage ('DOne');
end;

AVエラーが発生しています。サイズが1024倍のメモリを作成すると問題を軽減できますが、それでも発生する場合があります。

私は何か間違ったことをしていますか?

4

1 に答える 1

11

あなたのコードは大丈夫です。使用しているTStringBuilderコードに問題があります。この方法を検討してください。

procedure TStringBuilder.Append(const AString : string); 
var iLen : integer; 
begin 
  iLen := length(AString); 
  if iLen + FIndex > FBuffMax then _ExpandBuffer; 
  move(AString[1],FBuffer[FIndex],iLen); 
  inc(FIndex,iLen); 
end;

将来の長さが現在のバッファサイズに対して長すぎる場合、バッファは拡張されます。_ExpandBufferバッファのサイズを2倍にしますが、一度それが行われると、新しいバッファサイズが十分であるかどうかをチェックすることはありません。元のバッファサイズが1024で、ロードするファイルが3 KBの場合、バッファサイズを2倍にして2048にすると、バッファが小さすぎて、Appendバッファの終わりを超えて1024バイトが上書きされることになります。 。

ifwhileinに変更しAppendます。

于 2011-08-08T16:07:18.673 に答える