3

TOpenDialogコンポーネント(OpenDialog1)とボタン を含むフォームがあります。(of )プロパティがtrueに設定されていますOpenDialog1ofAllowMultiSelectOptions

ボタンをクリックすると、メソッド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;

アプリケーションを実行して最初のファイルを選択しても問題はありませんが、2番目のファイルを選択しようとすると、「Projectproject3で例外クラスEInvalidPointerが発生しました。メッセージは「InvalidPointerOperation」です。」というエラーが表示されます。

これの原因は何ですか、どうすればこれを修正できますか?

4

3 に答える 3

23

「無効なポインタ操作」とは、自分のものではないメモリを解放したことを意味します。これらの3つのことの1つが原因です:

  • あなたのプログラムは、以前に一度解放されたものを解放しました。
  • あなたのプログラムは、そもそも割り当てられなかったものを解放しました。
  • プログラムは、別のメモリマネージャに割り当てられていたものを解放しました。

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 に答える