2009-06-30 129 views
3

我有一个包含TOpenDialog组件(OpenDialog1)和一个按钮的窗体。 OpenDialog1ofAllowMultiSelect(的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,并显示消息'Invalid Pointer Operation'。“

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

回答

22

“指针操作无效”表示释放了不属于您的内存。其中之一是原因:

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

在您的代码中,您将释放TOpenDialogFiles属性。您没有分配该字符串列表,并且文档没有告诉您释放它,所以期望列表实际上属于对话框组件并且该组件将在需要时将其释放,这是合理的。检查中的源代码Dialogs.pas证实了这一点。既然你也已经释放了这个对象,那么你就有一个双重的错误,它符合我上面列出的第一个标准。删除该行。

由于Uwe pointed out,您还正在处理列表的文件名,但只检查一个的存在。这是程序中的逻辑错误,但它不会导致您看到的异常。

+0

除了释放不属于您的内存之外,您可以获得无效指针操作异常。它只是意味着你跟随了一个糟糕的指针。释放别人的数据是其中一个原因,而不是它的唯一原因。 – 2009-06-30 23:17:33

3

您应该检查

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

,而不是

if FileExists(OpenDialog1.FileName) then begin 

更好的投资在一个局部变量保存该值。

为什么这样?

OpenDialog1.Files.Free; 
+0

嗨Uwe,我改变'如果FileExists(OpenDialog1.Files [I])然后开始',我注释掉这一行:OpenDialog1.Files.Free; 并且错误消失。看起来最后一行是导致问题的原因。 – Attilah 2009-06-30 18:03:09

2

文件归属于TOpenDialog,不应直接释放。