Entwickler-Ecke

Sonstiges (Delphi) - Zuweisung in einem array spinnt


Black Lightning - Di 30.07.02 11:52
Titel: Zuweisung in einem array spinnt
Hallo,
seit Tagen such ich nun einen Fehler von dem ich dachte das er gar nicht möglich sei, nun da ich ihn auf eine Codezeile begrentzen konnte, weiss ich dass er nicht möglich ist, aber urteilt selbst:
Also ich hab ein 3 dimensionales Array of string namens Film.
Die Codezeile enthält folgende Zuweisung:

Quelltext
1:
Film[1,1,0] := Film[0,0,0]                    

Das lustige daran ist (nein es ist nicht lustig sondern zum wahnsinnig werden), dass nicht nur Film[1,1,0] den Wert von Film[0,0,0] erhält, sondern auch Film[0,1,0].

Ich dachte schon ein Neustart des Computers wär von nutzen, aber leider nicht.
Falls jemand eine rationale Erklärung (ach von mir aus kann sie auch irrational sein) für dieses Verhalten hat, dann würd ich das gerne wissen, denn ich weiss nicht was ich jetzt machen soll. Diesen Fall hatte ich noch nie: Fehler suchen -> Fehler finden -> Fehler nicht möglich -> Problem

gruß
Black Lightning


Klabautermann - Di 30.07.02 13:51

Hallo,

klingt für mich wirklich sehr ungewöhnlich. KAnnst du bitte etwas von dem Drumherum Posten? Also wie wird das(die) Array(s) Deklariert und was stellst du sonst noch mit denen an?

Gruß
Klabautermann


Black Lightning - Di 30.07.02 17:09

also bei dem Programm soll es sich mal um eine Movie-Database handeln.
Erstellt habe ich sie mit Delphi 6 Personal Edition, erste Version, also nicht geupdatet.
Das 3-dimensionale array namens Film dient als speicher. Film[0] ist die originalliste wie sie gespeichert und auch geladen wird. Film[1] ist Film[0] aber sortiert, Film[2] ist Film[1], aber nach gewissen Kriterien eigeschränkt, ist aber noch nicht programmiert.
In der zweiten Dimension sind die Filme eigetragen und in der dritten die Eigenschaften der Filme, also Titel, Größe, Sprache etc.

ich hab hier mal den Quellcode zum Download bereitgestellt, der Fehler ist in der sortier Funktion, In Unit 3.

http://www.programmers-club.de/~skfink/Delphi/Das%20Problem.zip

gruß
Black Lightning

EDIT: Um das Proplem genau zu sehn ist es am besten 2 Filme einzutragen (Strg N), dann liste speichern (Strg S), und bei jedem Start des Programms sieht man diese irrationale Veränderung in einer message.


Black Lightning - Mi 31.07.02 16:58

hat sich das jemand mal angeschaut? Oder muss ich das als Bug von Delphi abtun und das Prog umschreiben?

mfg

Black Lightning


Klabautermann - Mi 31.07.02 17:28

Hallo,

ich habe gestern nur kurz reigeguckt, hatte aber noch probleme deiner Logik zu folgen (soll keine Kritik sein, das ist normal wenn man sich mit den Programmen anderer Leute auseinander setzt). Kannst du mir sagen in welcher Zeilennummer du den Fehler vermutest? Dann kann ich vieleicht geziehlter suchen. Auf jeden fall werde ich nacher noch mal reingucken.

Gruß
Klabautermann


aogwaba - Mi 31.07.02 18:59

Hi
Habe den Code mal überflogen.
(ist ja ziemlich viel)

Du weist hoffentlich das bei einem dyn. Array mit der Anweisung
Array1:=Array2;
nur die Zeiger kopiert werden,
und bei:
if Array1 = Array2
wird geprüft wird ob beide Array's auf den selben Speicherbereich zeigen.

Dyn. Array's sind eigentlich Zeiger Arrays.

cu
waba


Black Lightning - Mi 31.07.02 21:42

erstmal danke dass ihr euch die Mühe macht.
Der Fehler, oder zumindest das Autreten eines vielleicht zuvor gemachten Fehlers ist in Unit 3 Zeile 129
Die Zeile ist zwischen 2 showmessage befehlen, anhand welcher man gut sieht was die Fehlfunktion genau ist. (Dazu muss man eine Movieliste mit 2 verschiedenen Filmen erstellen)
Da die create methode der form die liste automatisch lädt und anschliessend sortiert sieht man die messages noch vor erscheinen der form, relevant dabei ist die erste und zweite message, bzw die Veränderung der beiden in der man sieht daß, obwohl nur eine Zuweisung zwischen den beiden messages steht, dass 2 array werte verändert wurden.
In meinem Fall hab ich in meiner Liste Stigmata und Outbreak. In der ersten Message kommt Outbreak Outbreak Stigmata Stigmata, was auch stimmt, als nächstes sollte Outbreak Stigmata Stigmata Stigmata kommen, es es kommt Stigmata Stigmata Stigmata Stigmata.

ich hoffe ich hab das Problem verständlicher gemacht und keine Verwirring produziert (welche zeitweise beim schreiben dieses Postings bei mir selbst auftrat)


Ich werd mir mit den neuen Erkentnissen was Array1 := Array2 angeht (es war mir nämlich nicht bewusst das dabei nur der Zeiger geändert wird) das ganze nochmal durchgehn und schauen wie sich das auswirken könnte.


gruß
Black Lightning


Black Lightning - Mi 31.07.02 22:07

also mir ist jetzt klar was passiert ist.
in der create methode der form1 sag ich film[1] := film[0] und lasse dann sortieren.
dort wird in der besagten Zeile 129 einige werte von Film[1] verändert, aber dabei ist Film[1] und Film[0] ja das gleiche Array.

(und ich Depp wollte schon Delphi die Schuld geben :lol: )

um das Problem aus der Welt zu schaffen wollte ich nun eine Prozedur schreiben, welche die Arrays wirklich kopiert.

Aber leider nimmt Delphi die Deklaration nicht an:


Quelltext
1:
2:
procedure array_angleichen(OriginalArray: array of array of string;
                KopierArray: array of array of string);


beim zweiten array meckert Delphi soll ein Identifier stehn....wie mach ich das denn klar das es sich um ein mehrdimensionales dynamisches Array handelt?

gruß
Black Lightning


Tpercon - Mi 31.07.02 22:18

Schon in der ersten Zeile der Function wird bei mir schon gemeckert und zwar bei zweiten Wort array (Bezeichner erwartet, aber ARRAY gefunden).

Gruß


aogwaba - Mi 31.07.02 22:28

musst sicher einen neuen Typ erstellen:

type
myarray= array of array of array of string;


cu
waba


Black Lightning - Do 01.08.02 11:19

ich hab jetzt einen Type erstellt: TFilm = array of array of string
die Variable Film ist nun array of TFilm und in die Procedure wird nun 2 Parameter des Typs TFilm übergeben.

Die Procedure sieht folgendermaßen aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure arrays_angleichen(OriginalArray: TFilm; KopierArray: TFilm);
var x, y: integer;
Begin
  if length(OriginalArray) = 0 then exit;
  setlength(KopierArray, length(OriginalArray), anz+1);
  for x:= 0 to length(OriginalArray)-1 do
  for y:= 0 to anz do
  KopierArray[x,y] := OriginalArray[x,y];
end;

aufgerufen wird sie so:arrays_angleichen(Film[0],Film[1]);
das Problem ist nur dass es nicht funktioniert. Das KopierArray ist zwar am Schluss gleich dem OriginalArray, aber Film[1] bleibt so wie es zum Zeitpunkt der Parameterübergabe war.
Es wird also nur der Wert bzw die Werte von Film[1] als Parameter übergeen und nicht Film[1] selbst. Was ja auch einigermaßen einleuchtend ist. Aber bedeutet dass nun dass es keine Möglichkeit gibt das in eine Procedure zu packen.....muss ich den Algorithmus jedesmal erneut hinschreiben?

gruß
Black Lightning


wwerner - Do 01.08.02 11:52


Quelltext
1:
procedure arrays_angleichen(OriginalArray: TFilm; var KopierArray: TFilm);                    


Black Lightning - Do 01.08.02 12:52

thx :wink:
endlich endlich nach Tagelanger Verzweiflung läufts :D

gruß
Black Lightning