Страница 1 из 1

FindNext - Access violation

СообщениеДобавлено: 09.01.2010 16:41:52
author
Добрый день.

Код: Выделить всё
  function TLocator.Locate( Path : String ) : Boolean;
  var
    Info : TSearchRec;
    i : Integer;
  begin
    i := 0;
    if ( FindFirst( Path + '*', faAnyFile AND faDirectory, Info ) = 0 ) then
      repeat
        if Info.Name = '.' then
          continue;
        List[i].name := Info.Name;
        List[i].fullpath := Path + Info.Name;
        if ( Info.Attr AND faDirectory ) = faDirectory then
          begin
            List[i].directory := true;
            List[i].fullpath := List[i].fullpath + '/';
          end;
        i := i + 1;
      until ( FindNext( Info ) <> 0 );
    FindClose( Info );

    if i = 0 then
      Locate := false
    else
      begin
        Root := Path;
        Count := i - 1;
        Locate := true;
      end;
  end;


При первом вызове отрабатывает, при втором валится на FindNext, вне зависимости от директории.
Не могу понять в чем дело. Может быть кто подскажет. Спасибо.

An unhandled exception occurred at $0805A086 :
EAccessViolation : Access violation
$0805A086
$0804A24F
$08072670
$08060ECF
$08060B13
$08048BAB
$08048C4D

fpc 2.2.0

Re: FindNext - Access violation

СообщениеДобавлено: 09.01.2010 16:57:24
AbakAngelSoft
Валится наверное на List[i]? Где создаются элементы массива или списка?

Re: FindNext - Access violation

СообщениеДобавлено: 09.01.2010 17:05:28
author
валится там, где я написал

Код: Выделить всё
      repeat
        if i <> 0 then
          writeln( 'FindNext end' );
        if Info.Name = '.' then
          continue;
        List[i].name := Info.Name;
        List[i].fullpath := Path + Info.Name;
        if ( Info.Attr AND faDirectory ) = faDirectory then
          begin
            List[i].directory := true;
            List[i].fullpath := List[i].fullpath + '/';
          end;
        i := i + 1;
        writeln( 'FindNext begin' );
      until ( FindNext( Info ) <> 0 );


FindNext begin
An unhandled exception occurred at $0805A086 :
EAccessViolation : Access violation
$0805A086
$0804A24F
$08060F0C
$08060B13
$08048BAB
$08048C4D

Re: FindNext - Access violation

СообщениеДобавлено: 09.01.2010 17:28:09
Astralis
можете заметить, что
Код: Выделить всё
faAnyFile AND faDirectory = faDirectory

так что в вашем примере будут только каталоги. теоретически может существовать не только каталог . но каталог .. всех их надо пропускать,
проверять на соответствие атрибутов каталогу тоже наверное лишнее (раз тут могут быть исключительно каталоги).
список list должен уже быть создан и инициализирован и все его элементы сконструированы, но мне интересно, а как вы заранее узнали его размер. попробуйте прогнать ту программу без list
код инициализации list в студию

Re: FindNext - Access violation

СообщениеДобавлено: 09.01.2010 19:38:43
AbakAngelSoft
Автор же уверен что с list все в порядке :) ! Зачем его инициализировать? Это все разработчики lazarus виноваты! :)

Re: FindNext - Access violation

СообщениеДобавлено: 10.01.2010 00:49:21
Odyssey
author писал(а):An unhandled exception occurred at $0805A086 :
EAccessViolation : Access violation
$0805A086
...

Хм, если включить в опциях проекта "Выдавать номера строк в ошибках времени исполнения", то по идее рядом с адресами должны будут появиться названия вызываемых функций и номера строк. С этой информацией было бы проще понять в чём дело.

И для чистоты эксперимента, было бы здОрово поставить writeln('FindNext end'); следом за циклом. Мало ли, может быть FindNext уже возвращает что-то отличное от нуля, и программа падает после выхода из цикла.

Re: FindNext - Access violation

СообщениеДобавлено: 10.01.2010 09:49:17
sign
Ясно дело, с List наглючил, потому и не желает показать нам весь код.

Re: FindNext - Access violation

СообщениеДобавлено: 10.01.2010 15:48:10
Padre_Mortius
Интересно кто-нить из отписавшихся проверил код? )))

Если я правильно понял это не весь код. Вот уж не знаю, что хочет сделать автор, но проблемы в алгоритме тоже есть. Некоторые файлы данный алгоритм считает за папки и сканирует только текущую папку.

Для начала думаю стоит автора отправить почитать Базу Знаний http://freepascal.ru/forum/viewtopic.php?f=35&t=5013

Re: FindNext - Access violation

СообщениеДобавлено: 11.01.2010 16:13:35
author
Astralis
с чего Вы взяли что будут обрабатываться только каталоги?
если внимательно прочитать код, то видно, что в случае, если каталог, то просто пометить что это каталог, и далее обработка следующего элемента (файла или каталога, без разницы)

AbakAngelSoft
с List[] все в порядке

Odyssey
естественно я это проверял через writeln, падало именно на FindNext
а за опцию спасибо, удобная штука, не использовал, так как компилю из консоли

sign
см выше

Padre_Mortius
Padre_Mortius писал(а):Некоторые файлы данный алгоритм считает за папки и сканирует только текущую папку

вот тут можно поподробнее?

2all
Проблема решилась после нахождения ошибки в другом месте кода - после StrAlloc забыл StrDispose,
и так при нескольких повторных вызовах того кода. Странно что всплыло это именно на FindNext.
чем то напоминает приколы в Си

Re: FindNext - Access violation

СообщениеДобавлено: 11.01.2010 16:40:14
Padre_Mortius
вас самого данный кусок кода не смущает?
Код: Выделить всё
       List[i].fullpath := Path + Info.Name;
        if ( Info.Attr AND faDirectory ) = faDirectory then
          begin
            List[i].directory := true;
            List[i].fullpath := List[i].fullpath + '/';
          end;

т.е. Вы сначала записываете в параметр List[i].fullpath путь к элементу, а потом проверяете атрибут fadirectory и меняете его. Имхо не совсем удачно. Может конечно я где-то ошибаюсь, но конструкция следующего вида будет более уданой
Код: Выделить всё
        if ( Info.Attr AND faDirectory ) = faDirectory then
          begin
            List[i].directory := true;
            List[i].fullpath := List[i].fullpath + '/';
          end else        List[i].fullpath := Path + Info.Name;

Re: FindNext - Access violation

СообщениеДобавлено: 11.01.2010 16:52:33
author
Padre_Mortius
тогда Ваш код тоже не очень удачен, нужно так)

Код: Выделить всё
        if ( Info.Attr AND faDirectory ) = faDirectory then
          begin
            List[i].directory := true;
            List[i].fullpath := Path + Info.Name + '/';
          end
        else
           begin       
             List[i].directory := false;
             List[i].fullpath := Path + Info.Name;
           end;


но это все мелочи

Re: FindNext - Access violation

СообщениеДобавлено: 11.01.2010 17:42:34
sign
Тоже мелочь, но....
Код: Выделить всё
    List[i].fullpath := Path + Info.Name;
    List[i].directory := (Info.Attr AND faDirectory) = faDirectory;
    if List[i].directory then List[i].fullpath := List[i].fullpath + '/';

Re: FindNext - Access violation

СообщениеДобавлено: 11.01.2010 17:50:30
author
sign
а Padre_Mortius ответит на это
Padre_Mortius писал(а):т.е. Вы сначала записываете в параметр List[i].fullpath путь к элементу, а потом проверяете атрибут fadirectory и меняете его.

:lol:

Добавлено спустя 59 секунд:
в общем всем спасибо, прога уже работает и радует меня