Неверная операция указателя
-
21-08-2019 - |
Вопрос
У меня есть форма, содержащая 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 с сообщением «Недопустимая операция с указателем».
В чем причина этого, как это исправить?
Решение
«Недопустимая операция с указателем» означает, что вы освободили память, которая вам не принадлежала.Одна из этих трех вещей является причиной:
- Ваша программа освободила то, что уже было освобождено однажды.
- Ваша программа освободила что-то, что никогда не было выделено.
- Ваша программа освободила что-то, что было выделено другим менеджером памяти.
В своем коде вы освобождаете TOpenDialog
's Files
свойство.Вы не выделяли этот список строк, и в документации не указано, что вам нужно освободить его, поэтому разумно ожидать, что список на самом деле принадлежит компоненту диалога, и что компонент освободит его, когда захочет.Проверяем исходный код в Диалоги.пас подтверждает это.Поскольку вы также освободили этот объект, у вас есть ошибка двойного освобождения, которая соответствует первому критерию, который я перечислил выше.Удалите эту строку.
Как Уве отметил, вы также обрабатываете список имен файлов, но проверяя только существование одного из них.Это логическая ошибка в вашей программе, но она не приведет к тому исключению, которое вы видите.
Другие советы
Вам следует проверить
if FileExists(OpenDialog1.Files[I]) then begin
вместо
if FileExists(OpenDialog1.FileName) then begin
Лучше инвестируйте в локальную переменную, содержащую это значение.
И почему это?
OpenDialog1.Files.Free;
Файлы принадлежат TOpenDialog и не должны освобождаться напрямую.