Entwickler-Ecke
Sonstiges (Delphi) - access violation -> Warum?
Gausi - Di 25.02.03 15:55
Titel: access violation -> Warum?
ich bekomme eine Access violation at adress (..) in Module (..). Write of Adress (..) und weiss nicht warum.
Ich schreibe ein Programm, dass zu verschiedenen Terminen jeweils eine bestimmte Personenliste ausgibt. Das mache ich im wesentlichen mit einer rekursiven Prozedur, die alle möglichen Personenkombinationen durchprobiert, und nach bestimmten Kriterien eine "gute" als Ergebnis liefert. Hier der ungefähre Quellcode (ich hab einige Sachen der Übersichtlichkeit wegen in Pseudocode übersetzt:)
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure Mainform1.suche(pos:integer) var i:integer; begin if besterwert>abbruchgrenze then exit; for i:=pos to {anzahl verfügbarer Personen} do begin if {Person kann an dem Termin} then {füge Person in die Liste ein} if {noch zuwenig Personen} then suche(i+1); end; if {richtige personenanzahl in Liste} then begin memo1.lines.append('Versuche tmpwert zu setzen'); tmpwert:=bewertung({Personenliste}); memo1.lines.append('tmpwert gesetzt'); if tmpwert>besterwert then {merke diese Liste und aktualisiere besterwert} end; (*) if besterwert>abbruchgrenze then exit else {entferne grade eingefügte Person wieder und suche weiter} end; |
Noch zur Erklärung: "Bewertung" ist eine Funktion, die einen integer-Wert liefert, "abbruchgrenze" ist ein fester Wert, "besterwert" ist globale Variable, "tmpwert" wahlweise global oder lokal (es klappt beides nicht).
Die Abfrage zu Beginn soll verhindern, dass ALLE Kombinationen durchgeprüft werden, sondern bei einer guten gefunden Kombination die Rekursion abbricht.
Die "Access Violation" geschieht bei der Zuweisung "tmpwert:=bewertung{personenliste}). Einfach daran zu erkennen, dass "Versuche tmpwert zu setzen" noch ausgegeben wird, ebenso die Nachricht, dass "bewertung" erfolgreich beendet wurde. Die Meldung "tmpwert gesetzt" dagegen nicht.
Weiteres Kuriosum: Wenn ich die Abbruchbedingung (*) in
Quelltext
1:
| if tmpwert>abbruchgrenze |
ändere, läuft es glatt durch.
Kann da einer weiterhelfen?
Keldorn - Di 25.02.03 16:15
Hallo
kannst du mal den originalen Quelltext posten?
Personenliste - wie ist die deklariert?
und wie sieht der quelltext bei Bewertung aus?
Mfg Frank
Gausi - Di 25.02.03 16:54
hmmm.. den originalen Quelltext poste ich lieber nicht. Der ist erstens ziemlich lang, und recht unübersichtlich, da ich nicht nur eine Liste darin habe, sondern mehrere.
Noch etwas zum Prinzip des Programms:
Ich habe eine Liste von Personen. Diese Liste steht in einer Tlistbox, wobei hinter jedem Eintrag ein Objekt vom Typ "Person" steht. "Person" hat u.a. die Attribute "name", "Geburtstag", "Urlaubsliste" und "istinaktullerliste" etc. (Urlaubsliste ist eine Stringlist, in der die einzelnen Urlaubstage stehen)
"istinaktullerliste" ist ein boolean wert, der später gebraucht wird.
Das sind die verfügbaren Personen.
Dann habe ich eine Liste von Terminen. Ein Termin hat u.a. die Eigenschaften "Datum", "Anzahlbenötigter Personen" und "Personenliste". Diese Personenliste ist ein dynamisches Array vom Typ "Person", dessen Länge nach Eingabe der benötigten Zahl gesetzt wird.
Die Verwaltung all dieser Listen wurde schon ausgiebig getestet, da dürfte kein Fehler mehr drin liegen.
Die Hauptprozedur des Programms führt jetzt im wesentlichen folgende Schleife durch:
Quelltext
1:
| for i:=0 to terminliste.count-1 do suche(i,1) |
Der erste Parameter gibt die Terminnr an, der zweite steuert die Position, ab der in der Liste der verfügbaren Personen gesucht wird.
Wenn in der Prozedur suche eine Person eingefügt wird, wird der Wert "istinaktuellerliste" auf true gesetzt. Darüber kann ich rausfinden, welche Personen ich grade betrachte, ohne noch eine neue liste zu erstellen.
In der Funktion "Bewertung" wird aus den Personen mit "inaktuellerliste=true" ein Array gefüllt, was dann genauer untersucht wird. Ergebnis dieser Funktion ist auf jeden Fall ein Integer Wert, den ich mit dem besten zuvor gefunden Wert vergleichen möchte.
Nur kommt da die Access Violation. Selbst wenn ich nochsoviel quatsch mit den dynamischen Arrays und listen mache, dann dürfte die Zuweisung eines IntegerWertes an eine Integer Variable doch nicht schiefgehen, oder?
Delete - Di 25.02.03 21:28
Quelltext
1:
| for i:=pos to {anzahl verfügbarer Personen} |
Was ist der Startwert von pos?
Außerdem nimm mal einen andern Variablennamen
pos ist schon eine Funktion aus der System.pas
Versuch die Schleife mal bis {anzahl verfügbarer Personen}
-1 laufen zu lassen.
Gausi - Mi 26.02.03 16:52
@ Luckie
Der Startwert von pos war 1 (hab ich mittlerweile auf 0 korrigiert), und
obere Grenze hatte ich anzahl-1, nur im Pseudocode hab ich das weggelassen ;-)
---
Das Problem hat sich mitlerweile erledigt, hab die Datenorganisation etwas verändert - weg von Arrays hin zu TObject- und anderen Listen, und das 3-fach verschachtelt. Unübersichtlich auf den ersten Blick, aber ein besseres System glaube ich-- und es klappt :-)
Danke trotzdem für die Mühe!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!