【问题标题】:Invalid Pointer Operation无效的指针操作
【发布时间】:2009-06-30 17:39:51
【问题描述】:

我有一个包含 TOpenDialog 组件 (OpenDialog1) 和按钮的表单。 OpenDialog1 的 ofAllowMultiSelect(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;

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

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

【问题讨论】:

    标签: delphi openfiledialog


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 除了释放不属于您的内存之外,您还可以获得无效指针操作异常。它只是意味着你跟随了一个错误的指针。释放其他人的数据是其原因之一,而不是唯一原因。
    • 跟随一个错误的指针通常会得到 EAccessViolation 或乱码数据,而不是 EInvalidPointer。例外情况是,如果您以某种方式覆盖编译器生成的 TTypeInfo 记录的 Kind 字段,在这种情况下,您可能会在 Initialize 或 Finalize 中或在分配记录或数组期间失败。与“释放不属于你的东西”相同的情况是,在引用计数为零之前释放引用计数的对象。 (搜索 reInvalidPtr 的源代码。)
    【解决方案2】:

    你应该检查

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

    而不是

    if FileExists(OpenDialog1.FileName) then begin
    

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

    为什么会这样?

    OpenDialog1.Files.Free;
    

    【讨论】:

    • 嗨 Uwe,我更改为 'if FileExists(OpenDialog1.Files[I]) then begin ',我注释掉了这一行:OpenDialog1.Files.Free;错误消失了。似乎最后一行是导致问题的原因。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-24
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多