Autor Beitrag
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Di 25.02.03 15:55 
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:)
ausblenden 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
ausblenden Quelltext
1:
 if tmpwert>abbruchgrenze					

ändere, läuft es glatt durch.

Kann da einer weiterhelfen?
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: 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

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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:

ausblenden 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?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 25.02.03 21:28 
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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!