3

我有一个包含TOpenDialog组件 ( OpenDialog1) 和按钮的表单。 OpenDialog1ofAllowMultiSelect(of Options) 属性设置为 true。

单击按钮后,将AddFilesToListView执行该方法:

procedure TForm4.AddFilesToListView();
var
  ListItem : TListItem;
  I: Integer;
  F : File;
  LengthOfAudio : TDateTime;
  previousCursor : TCursor;

begin
  previousCursor := Self.Cursor;
  Self.Cursor := crHourGlass;

  if OpenDialog1.Execute then
  begin
    for I := 0 to OpenDialog1.Files.Count - 1 do begin
      if FileExists(OpenDialog1.FileName) then begin
        ListItem:=ListView1.Items.Add;
        ListItem.Caption := 'Test';
        ListItem.SubItems.Add(ExtractFileName(OpenDialog1.Files[I]));
        ListItem.SubItems.Add(ExtractFilePath(OpenDialog1.Files[I]));
      end else
        raise Exception.Create('File does not exist.');
    end;
  end;

  Self.Cursor := previousCursor;

  OpenDialog1.Files.Free;
end;

运行应用程序时,选择第一个文件,我没有问题,但是当我想选择第二个文件时,我收到一条错误消息“Project project3 引发了异常类 EInvalidPointer 并带有消息'无效指针操作'。”

这是什么原因,我该如何纠正?

4

3 回答 3

23

“无效的指针操作”意味着您释放了不属于您的内存。这三件事之一是原因:

  • 你的程序释放了之前已经释放过一次的东西。
  • 您的程序首先释放了从未分配过的东西。
  • 您的程序释放了一些已分配给不同内存管理器的东西。

在您的代码中,您正在释放TOpenDialog'Files属性。您没有分配该字符串列表,文档也没有告诉您释放它,因此可以合理地预期该列表实际上属于对话框组件,并且该组件会在需要时释放它。检查Dialogs.pas中的源代码可以确认这一点。由于您还释放了该对象,因此您有一个双重释放错误,它符合我上面列出的第一个标准。删除该行。

正如Uwe 指出的那样,您还在处理文件名列表,但只检查一个文件名的存在。这是您的程序中的逻辑错误,但不会导致您看到的异常。

于 2009-06-30T18:27:26.577 回答
3

你应该检查

if FileExists(OpenDialog1.Files[I]) then begin

代替

if FileExists(OpenDialog1.FileName) then begin

最好投资于持有该值的局部变量。

为什么会这样?

OpenDialog1.Files.Free;
于 2009-06-30T17:53:54.370 回答
2

文件归 TOpenDialog 所有,不应直接释放。

于 2009-06-30T18:36:58.107 回答