+ -
当前位置:首页 → 问答吧 → 报Access violation at address xxxxx in module

报Access violation at address xxxxx in module

时间:2011-12-06

来源:互联网

小弟初学delphi 一个自动上传文件同时改订单状态的程序 下面的代码是用timer调用的
当程序运行时间长了以后就会报错
那个“xxxxxx”会变的,每次不一样 in module 有时候有 有时候没
Delphi(Pascal) code

procedure TForm1.downListAndUpload();
var
  i: Integer;
  j: Integer;
begin
  ListView1.Clear();
  Panel2.Visible := false;

  //下载FTP上的文件列表
  if not FileExists(ExtractFilePath(Paramstr(0)) + userName + '.txt') then
  begin
    FtpLibrary1.localpath := ExtractFilePath(Paramstr(0)) + userName + '.txt';
    FtpLibrary1.remotepath := userName + '.txt';
    if FtpLibrary1.ExistFile(userName + '.txt') then
    begin
      if FtpLibrary1.Download() then
        FtpLibrary1.DeleteFile(userName + '.txt');
    end
    else
    begin
      if CheckBox3.Checked = true then
        //自动关机
        ShutDown();
    end;
  end;
  //列表存在 解析文件列表 加入listview
  if FileExists(ExtractFilePath(Paramstr(0)) + userName + '.txt') then
  begin
    mystring := TStringlist.Create;
    mystring.LoadFromFile(ExtractFilePath(Paramstr(0)) + userName + '.txt');
    list := TStringlist.Create;
    ExtractStrings(['|'], [], Pchar(mystring.text), list);
    mystring.Free;
    //增加
    for i := 0 to list.Count - 1 do
    begin
      sub := TStringlist.Create;
      ExtractStrings(['$'], [], Pchar(list[i]), sub);
      ListItem := ListView1.Items.Add;
      ListItem.Caption := StringReplace(sub[0], ' ', '', [rfReplaceAll]);  //添加标题
      ListItem.SubItems.Add(inttostr(i));
      sub.Free;
    end;

    FtpLibrary1.Encoding := 'UTF8';
    FtpLibrary1.ReplaceSetting := 2;
    isUpdating := true;

    //上传到服务器

    for i := 0 to list.Count - 1 do
    begin
      sub := TStringlist.Create;
      ExtractStrings(['$'], [], Pchar(list[i]), sub);
      FtpLibrary1.localpath := sub[0];
      tempWide := sub[0];
      tempWide := ExtractFileName(tempWide);

      FtpLibrary1.remotepath := string(tempWide);

      if FtpLibrary1.Upload() then
      begin
        url := baseUrl+'/clientlogin!updateOrdersByFileName?orderCode='
          + sub[1];
        Idhttp1.HandleRedirects := true;     //必须支持重定向否则可能出错
        Idhttp1.ReadTimeout := 5000;         //超过这个时间则不再访问
        try
          s := Idhttp1.Get(url);
        except
          url := baseUrl1+'/clientlogin!updateOrdersByFileName?orderCode='
          + sub[1];
          try
            s := Idhttp1.Get(url);
          except
            s := 'fail';
          end;
        end;

        for j := 0 to listview1.Items.Count - 1 do
        begin
          if SameText(ListView1.Items[j].Caption,sub[0]) then
          begin
            ListView1.Items.Delete(j);
          Break;
          end;
        end
      end
      else
      begin
        for j := 0 to listview1.Items.Count - 1 do
        begin
          if SameText(ListView1.Items[j].Caption,sub[0]) then
            ListView1.Items.Delete(j);
          Break;
        end;
      end;
    end;
    list.Free;
    sub.Free;
    isUpdating := false;
    Panel2.Visible := true;
    //上传完删除文件列表
    sleep(1000);
    DeleteFile(ExtractFilePath(Paramstr(0)) + userName + '.txt');
  end;
  Timer1.Enabled := true;
end;


作者: laiwenti   发布时间: 2011-12-06

顶一下先 那个ftplibrary1 是第三方控件

作者: laiwenti   发布时间: 2011-12-06

还是没人来 - -

再顶

作者: laiwenti   发布时间: 2011-12-06

人呢人呢人呢人呢人呢人呢人呢人呢人呢人呢人呢

作者: laiwenti   发布时间: 2011-12-06

你的问题说明的还是不清楚,不确定问题是不是在这里。
一般有删除的情况下,循环都是从高到低的,否则,就会出现数据溢出的,比如:本来是10条,你删除1条,剩9条,你的循环还去找第10条,肯定会出错的。
Delphi(Pascal) code

        for j := 0 to listview1.Items.Count - 1 do//应改为for j := listview1.Items.Count - 1 to 0
        begin
          if SameText(ListView1.Items[j].Caption,sub[0]) then
            ListView1.Items.Delete(j);
          Break;
        end;


作者: babydog01   发布时间: 2011-12-06

不好意思 ,for 向下循环用 downto :
Delphi(Pascal) code

for j := listview1.Items.Count - 1 downto 0

作者: babydog01   发布时间: 2011-12-06

可能是上一个Timer没有执行结束,后一下Timer已经开始了,所以会出现访问公共变量/控件的值时发生冲突了
Timer1执行了应该设置Enabled := flase;
downListAndUpload执行结束后再设置Enabled := true;

作者: kaikai_kk   发布时间: 2011-12-06

1 for i := 0 to list.Count - 1 do
  begin
  sub := TStringlist.Create;
  ExtractStrings(['$'], [], Pchar(list[i]), sub);
  ListItem := ListView1.Items.Add;
  ListItem.Caption := StringReplace(sub[0], ' ', '', [rfReplaceAll]); //添加标题
  ListItem.SubItems.Add(inttostr(i));
  sub.Free;
  end;
这里频繁的创建TStringlist然后释放,如果不是多线程程序,建议弄个全局的每次清空即可

2 倒序删除listview1中的项目,你这样写会有问题的
for j := 0 to listview1.Items.Count - 1 do
  begin
  if SameText(ListView1.Items[j].Caption,sub[0]) then
  begin
  ListView1.Items.Delete(j);
  Break;
  end;
  end

3 for i := 0 to list.Count - 1 do
  begin
  sub := TStringlist.Create;
这句sub := TStringlist.Create;是在for里创建,for循环外释放的,会内存泄漏

作者: funxu   发布时间: 2011-12-06

要删除ListView1符合记录的1笔还是删除全部,删除全部要从高到低删除
还有看看Break是否放错地方了;

作者: kaikai_kk   发布时间: 2011-12-06

热门下载

更多