You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi7中TStringList数组记录触发访问违规问题求助

问题分析与修复方案

核心错误:数组索引越界

你的代码存在数组索引越界问题,这是触发访问违规、乱码的直接原因:

  • 执行SetLength(RecArray, Length(RecArray)+1)后,数组的有效索引范围是0 ~ Length(RecArray)-1
  • 你直接用RecArray[RecLen](此时RecLen = Length(RecArray))访问数组,会写入到内存边界外的区域,破坏内存结构,导致后续数据混乱和访问错误

修复后的MakeRec代码

procedure TForm1.MakeRec(Arec : string);
var
  x : Integer;
  isThere : Boolean;
  NewIndex: Integer;
begin
  isThere := False;
  // 直接用IndexOfName判断ID是否存在,替代循环遍历,效率更高
  if iList.IndexOfName(Arec) <> -1 then
  begin
    isThere := True;
    Exit;
  end;

  if not isThere then
  begin
    NewIndex := Length(RecArray); // 新元素的索引为当前数组长度(从0开始计数)
    SetLength(RecArray, NewIndex + 1);
    // 初始化新记录
    RecArray[NewIndex].id := Arec;
    RecArray[NewIndex].Content := TStringList.Create;
    // 存储索引对应关系,注意保存的是实际索引值,而非数组长度
    iList.Add(Arec + '=' + IntToStr(NewIndex));
    ShowMessage(RecArray[NewIndex].id + ' ' + IntToStr(iList.IndexOfName(Arec)));
    RecLen := Length(RecArray); // 可选:若需保留数组长度则更新
  end;
end;

额外优化与注意事项

  • 内存泄漏防护:处理完文件后,必须先遍历RecArray释放每个元素的Content对象,再重置数组:
    var
      i: Integer;
    begin
      for i := 0 to Length(RecArray)-1 do
      begin
        RecArray[i].Content.Free;
      end;
      SetLength(RecArray, 0);
      iList.Clear;
    end;
    
  • 字符串类型兼容:记录中的string[2]是短字符串,若Arec是普通string(长字符串),赋值时需确保长度不超过2,或直接改用string类型避免截断风险
  • 大文件性能优化:处理25万行的大文件时,可提前给TStringList设置Capacity预分配内存,减少内存重分配次数

内容的提问来源于stack exchange,提问作者Learning

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:55:32