[Delphi] Onverklaarbare foutmelding in TSearchRec loop

Pagina: 1
Acties:

  • hornage
  • Registratie: November 2001
  • Laatst online: 24-09-2024
Ik ben bezig met een parser van een stel html files. De informatie uit de html files gaat ie parsen naar een mysql database. Dit loopt allemaal lekker alleen ik stuit op een foutmelding die niet geheel begrijp. Nadat ie al een aantal files heeft gehad maar zeker nog niet alle krijg ik een
Acces Violation op deze regel:
code:
1
      until FindNext(searchResult) <> 0;


Ik snap het probleem niet en zou niet weten hoe ik dit op kan lossen. Kan iemand me hier misschien mee helpen? Hieronder de gehele procedure:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TFrmMain.BtnConvertClick(Sender: TObject);
var
  searchResult : TSearchRec;
begin
  if ((BaseDir <> '') and (MySQL <> nil)) then begin
    LogHistory('check, dubbel check');
    if mysql_select_db(MySQL, pChar('stamperrors')) <> 0 then
      LogError('There was an error selecting the database')
    else begin
      FilList;
      if FindFirst(BaseDir + '\d*.html', faAnyFile, searchResult) = 0 then begin
        repeat
          Parse(BaseDir + '\' + searchResult.Name);
        until FindNext(searchResult) <> 0;
        FindClose(searchResult);
      end;
      LogHistory('Conversion finished');
    end;
  end
  else
    LogError('Connect to a database and select a dir');
end;

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Weet je zeker dat het op die regel is? Wat gebeurt er als je er stap voor stap heen loopt met de toets F8? En wat als je Use Debug DCUs aanzet in de Project Options en de functie FindNext in gaat? Waarom een AV? Is searchResult nil?

We adore chaos because we like to restore order - M.C. Escher


  • hornage
  • Registratie: November 2001
  • Laatst online: 24-09-2024
Weet je zeker dat het op die regel is?
ja, dat weet ik zeker, die regel wordt aangegeven tijdens de fout
Wat gebeurt er als je er stap voor stap heen loopt met de toets F8?
hetzelfde
En wat als je Use Debug DCUs aanzet in de Project Options en de functie FindNext in gaat?
dan wordt deze regel gekleurd:

unit System
procedure _LStrClr(var S);
code:
1
        MOV     ECX,[EDX-skew].StrRec.refCnt    { fetch refCnt                  }


Waarom een AV?
ik weet even zo niet wat dat is :?
Is searchResult nil?
nee, ik initialize hem met de findfirst regel

[ Voor 11% gewijzigd door hornage op 22-07-2005 16:08 ]


Verwijderd

Als je die regel met 'Parse' even wegcommentarieerd, doet hij het dan wel goed?

De fout MOET eigenlijk wel in die 'Parse' procedure zitten. Een AV (=access violation) komt bijna altijd doordat je een object probeert aan te spreken wat niet geinstantieerd is.

Stap nog eens door je code, maar druk dan, zodra hij op die regel met 'Parse' komt, niet op F8, maar op F7.

  • hornage
  • Registratie: November 2001
  • Laatst online: 24-09-2024
als parse weggecommentariseerd is doet hij het wel geheel goed. Fout moet dus toch bij parse zitten jah.
Ben nu bezig met alles aan het nalopen in parse.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

hornage schreef op vrijdag 22 juli 2005 @ 16:07:
Weet je zeker dat het op die regel is?
ja, dat weet ik zeker, die regel wordt aangegeven tijdens de fout
Wat gebeurt er als je er stap voor stap heen loopt met de toets F8?
hetzelfde
En wat als je Use Debug DCUs aanzet in de Project Options en de functie FindNext in gaat?
dan wordt deze regel gekleurd:
Waarom een AV?
ik weet even zo niet wat dat is :?
Is searchResult nil?
nee, ik initialize hem met de findfirst regel
De fout na een Exception zit altijd de regel er boven. Vandaar dat ik vroeg of je er even door heen wilde lopen met F8.

AV is Access Violation.

Als je ergens stopt kan je op de callstack kijken welke code allemaal doorlopen is. Daaraan zou je moeten kunnen zien waar de AV vandaan komt.

Je weet pas echt of searchResult nil is als je debugged, niet door aannames te doen.

Maar zo te zien is het al duidelijker waar de fout vandaan komt. Toch is het wel nodig dat je echt leert debuggen als je software wilt ontwikkelen.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Met F8 stap je 'over' de fout heen, als die in een andere procedure zit (zoals hier).

De aanroep 'Parse' levert een fout op, dus stopt hij op de regel erna.

Daarom gaf ik ook aan om voor de regel 'Parse' op F7 te drukken, dan springt hij de routine 'in' en kun je kijken wat er mis zit.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01:26

Tomatoman

Fulltime prutser

Hornage, je hebt in je code een geheugenlek, doordat FindClose als gevolg van de exception niet wordt uitgevoerd. Oplossing:
Delphi:
1
2
3
4
5
6
7
8
if FindFirst(..., SearchRec) = 0 then
  try
    repeat
      { doe hier iets met SearchRec }
    until FindNext(SearchRec) <> 0;
  finally
    FindClose(SearchRec);  // binnen een try..finally constructie!
  end;

Een goede grap mag vrienden kosten.


  • hornage
  • Registratie: November 2001
  • Laatst online: 24-09-2024
nou het is al iets duidelijker. doordat AV's worden weergegeven op de volgende regel code zat ik verkeerd te kijken. Na lang zoeken heb ik de fout gevonden maar ik zat dus eerst verkeerd te kijken.
Iedereen bedankt iig.

Verwijderd

Hornage, je hebt nog een bug.

Als het resultaat een directory oplevert, zal het waarschijnlijk ook fout gaan.

Verwijderd

Verwijderd schreef op zaterdag 23 juli 2005 @ 14:48:
Hornage, je hebt nog een bug.

Als het resultaat een directory oplevert, zal het waarschijnlijk ook fout gaan.
Op zich waar, maar dan moet hij wel rare directories hebben (d*.html)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01:26

Tomatoman

Fulltime prutser

Verwijderd schreef op zaterdag 23 juli 2005 @ 15:01:
[...]
Op zich waar, maar dan moet hij wel rare directories hebben (d*.html)
Maar het is ook heel eenvoudig op te lossen.
Delphi:
13
14
          if (searchResult and faDirectory) = 0 then
            Parse(BaseDir + '\' + searchResult.Name);

Een goede grap mag vrienden kosten.


Verwijderd

Tsja.. die hele code is een beetje smerig als je het mij vraagt. Ik kan nog wel een paar opmerkingen verzinnen m.b.t. deze code. De vraag uit de TS was echter waar die AV vandaan kwam, en dat is opgelost.

Zo noem ik een var 'Basedir' die kennelijk globaal is, evenals een var 'MySQL'. Zo noem ik het feit dat de logica in een OnClick event zit. Zo noem ik dat er twee log-functies zijn (logerror en loghistory) terwijl die praktisch hetzelfde doen (netter is dan bv. ' write_log(logtype,logentry)', enzovoort.

Voor de rest kan ik TS alleen maar adviseren eens wat goede boeken over Delphi te kopen (advies: Marco Cantu) en eens te gaan letten op onder andere identatie. Maar dat valt buiten het bestek van dit topic ;)

[ Voor 28% gewijzigd door Verwijderd op 23-07-2005 17:39 ]

Pagina: 1