为什么我使用 Mike Heydon 的 TStringBuilder 类会遇到访问冲突?
我正在使用从 .Net 移植到 Delphi 7 的 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 倍的内存时,可以缓解这个问题,但有时它仍然会发生。
我做错了什么吗?
I am using a TStringBuilder class ported from .Net to Delphi 7.
And here is my code snippet:
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;
I am experiencing AV errors. I can alleviate the problem when I create memory with the size multiple by 1024, however sometimes it still occurs.
Am I doing something wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的代码没问题。您使用的 TStringBuilder 代码有错误。考虑这种方法:
如果未来的长度对于当前缓冲区大小来说太长,则扩展缓冲区。
_ExpandBuffer
将缓冲区的大小加倍,但一旦完成,它就不会检查新的缓冲区大小是否足够。如果原始缓冲区大小为 1024,并且您要加载的文件为 3 KB,则将缓冲区大小加倍到 2048 仍然会使Append
中的缓冲区太小,最终会覆盖超出缓冲区末尾 1024 个字节。将
Append
中的if
更改为while
。Your code is fine. The TStringBuilder code you're using is faulty. Consider this method:
If the future length is too long for the current buffer size, the buffer is expanded.
_ExpandBuffer
doubles the size of the buffer, but once that's done, it never checks whether the new buffer size is sufficient. If the original buffer size is 1024, and the file you're loading is 3 KB, then doubling the buffer size to 2048 will still leave the buffer too small inAppend
, and you'll end up overwriting 1024 bytes beyond the end of the buffer.Change the
if
to awhile
inAppend
.