Entwickler-Ecke

Programmierwerkzeuge - Unterschiede im Programm bei Debug-/Releasekonfiguration


galagher - Fr 21.12.12 17:49
Titel: Unterschiede im Programm bei Debug-/Releasekonfiguration
Hallo!

Wie gibt's denn das: Mein Programm verhält sich jeweils anders, wenn ich mit Debug- oder Release-Konfiguration kompiliere!

Ich möchte zwei Strings vergleichen, und es arbeitet mindestens dieser Code hier anders, und zwar bei der Release-Konfiguration definitiv falsch, denn beim Vergleich der Strings "was ist Aas", "Aas ist Fleisch toter Tiere" (nicht lachen, bei diesem Text ist es mir aufgefallen!) wird dann oft 0, also keine Ähnlichkeit, zurückgegeben, dann wieder 18. Bei der Debug-Konfiguration ist der Rückgabewert immer 18.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
{http://groups.google.at/group/de.sci.informatik.misc/browse_thread/thread/7e28a09c69fd8b18/37ae33c36782ea32?lnk=st&q=%C3%A4hnlichkeit+zweier+strings+delphi&rnum=6&hl=de#37ae33c36782ea32}
function Similar(Str1, Str2: String): Integer;
VAR treffer, p1, p2, l1, l2, pt, diff: INTEGER;
     hstr: STRING;
    test: ARRAY [1..255OF BOOLEAN;
BEGIN
 if (Str1 = ''or (Str2 = ''then
 begin
  Result := -1;
  exit;
 end;

 {Hinzugefügt: Bei nur 1 Wort das 1. Zeichen des Strings als 2. Wort verwenden}
 if Pos(' ', Str1) = 0 then Str1 := Str1+' '+Str1[1];
 if Pos(' ', Str2) = 0 then Str2 := Str2+' '+Str2[1];

 IF Length(Str1) < Length(Str2) THEN BEGIN
  hstr:= Str2;  Str2:= Str1;  Str1:= hstr;
 END;
 l1:= Length (Str1);
 l2:= Length (Str2);
 p1:= 1;  p2:= 1;  treffer:= 0;
 diff:= Max (l1, l2) DIV 3 + ABS (l1 - l2);
 FOR pt:= 1 TO l1 DO  test[pt]:= FALSE;
 REPEAT
  IF NOT (test[p1]) THEN BEGIN
   IF (Str1[p1] = Str2[p2]) AND (ABS(p1-p2) <= diff) THEN BEGIN
    test[p1]:= TRUE;
    treffer:= Succ(treffer);
    p1:= Succ(p1);
    p2:= Succ(p2);
    IF p1 > l1 THEN p1:= 1;
   END ELSE BEGIN
    test[p1]:= FALSE;
    p1:= Succ(p1);
    IF p1 > Length(Str1) THEN BEGIN
     WHILE (p1 > 1AND NOT(test[p1]) DO  p1:= Pred(p1);
     p2:= Succ(p2)
    END;
   END;
  END ELSE BEGIN
   p1:= Succ(p1);
   IF p1 > Length(Str1) THEN BEGIN
    REPEAT
     p1:= Pred(p1);
    UNTIL (p1 = 1OR test[p1];
    p2:= Succ(p2)
   END;
  END;
 UNTIL p2 > Length(Str2);
 Result := 100 * treffer DIV l1;
end;


kkausp - Fr 21.12.12 18:14

Ich würde mal auf uninitialisierte Variablen tippen.


jaenicke - Fr 21.12.12 18:28

Die einzige Variable, die in der Hinsicht auffällig ist, ist test, da die aus irgendeinem Grund eine feste Länge hat, aber nur bis l1 befüllt wird. Danach stehen Zufallswerte drin. Es wäre vielleicht sinnvoller das Array komplett zu initialisieren oder nur so lang zu machen wie es sein muss.

// EDIT:
Ich hatte Recht...
Wenn du mal die Bereichsprüfung anschaltest und das Array mit SetLength dynamisch auf die initialisierte Größe, bekommst du einen Fehler bei der Bereichsprüfung. :zwinker:
// EDIT2:
Und zwar hier:

Delphi-Quelltext
1:
          WHILE (p1 > 1AND NOT(test[p1]) DO                    


galagher - Fr 21.12.12 18:33

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Die einzige Variable, die in der Hinsicht auffällig ist, ist test, da die aus irgendeinem Grund eine feste Länge hat, aber nur bis l1 befüllt wird. Danach stehen Zufallswerte drin. Es wäre vielleicht sinnvoller das Array komplett zu initialisieren oder nur so lang zu machen wie es sein muss.

// EDIT:
Ich hatte Recht...
Wenn du mal die Bereichsprüfung anschaltest und das Array mit SetLength dynamisch auf die initialisierte Größe, bekommst du einen Fehler bei der Bereichsprüfung. :zwinker:

Ok, da stehe ich jetzt an.
Kannst du mir einen Tipp geben, was genau ich ändern muss?


galagher - Fr 21.12.12 19:37

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Die einzige Variable, die in der Hinsicht auffällig ist, ist test, da die aus irgendeinem Grund eine feste Länge hat, aber nur bis l1 befüllt wird. Danach stehen Zufallswerte drin. Es wäre vielleicht sinnvoller das Array komplett zu initialisieren oder nur so lang zu machen wie es sein muss.

// EDIT:
Ich hatte Recht...
Wenn du mal die Bereichsprüfung anschaltest und das Array mit SetLength dynamisch auf die initialisierte Größe, bekommst du einen Fehler bei der Bereichsprüfung. :zwinker:

Ok, da stehe ich jetzt an.
Kannst du mir einen Tipp geben, was genau ich ändern muss?


//Edit:
Jetzt habe ich den Effekt auch bei Release:konfiguration! :eyecrazy:
Wie kann den ein und der selbe Stringvergleich unterschiedliche Ergebnisse liefern? Die Strings sind immer gleich, habe das getestet, sie werden nirgendwo verändert. Manchmal 0, manchmal 18.


richy-f - Fr 21.12.12 19:43

Wenn du wirklich wie der Vorredner auf nicht initialisierte Bereiche zugreifst oder außerhalb des Arraybereichs, wundert es eigentlich nicht. Da die Daten dort natürlich nicht immer gleich sind, wären die unterschiedlichen Ergebnisse nicht wirklich verwunderlich.


galagher - Fr 21.12.12 20:17

user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
Wenn du wirklich wie der Vorredner auf nicht initialisierte Bereiche zugreifst oder außerhalb des Arraybereichs, wundert es eigentlich nicht. Da die Daten dort natürlich nicht immer gleich sind, wären die unterschiedlichen Ergebnisse nicht wirklich verwunderlich.
Ich kapiere den Code, ehrlich gesagt, nicht...
Das Komische: Bei allen Tests ausserhalb des Projekts erhalte ich mit den selben Strings immer korrekte Results! Der Vergleich erfolgt doch immer gleich! Wie richte ich also das Array so ein, das es passt?

//Edit:
habe es jetzt so gemacht:


Delphi-Quelltext
1:
2:
3:
test: ARRAY OF BOOLEAN;
BEGIN
 SetLength(test, Length(Str1)+Length(Str2));

Sollte das falsch sein, bitte um Info (und wenn's richtig ist, bitte auch!) :wink:


richy-f - Fr 21.12.12 20:30

ist p1 immer kleiner als 256 ?


galagher - Fr 21.12.12 20:39

Beide Strings, Str1 und Str2, können 256 Zeichen nicht erreichen, aber das gilt nur für das aktuelle Projekt. Der Code sollte schon auch längere Strings vergleichen können.
user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
ist p1 immer kleiner als 256 ?
Wie gesagt, ich durchschaue den Code nicht ganz.


richy-f - Fr 21.12.12 20:45

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Beide Strings, Str1 und Str2, können 256 Zeichen nicht erreichen, aber das gilt nur für das aktuelle Projekt. Der Code sollte schon auch längere Strings vergleichen können.
user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
ist p1 immer kleiner als 256 ?
Wie gesagt, ich durchschaue den Code nicht ganz.

Also ich hab ihn ehrlich gesagt, nicht so genau angeschaut.

Aber p1 wird mit 1 initialisiert und zählt hoch über die succ funktion.
Dein Array test ist aufjedenfall fest auf eine Länge von 256 Einträgen fixiert und deine strings können ja größer sein.
Zumindest gehe ich mal davon aus, dass in Delphi die Länge nicht wie aus Urzeiten noch 256 ist.
Dann hättest du aufjedenfall an der Stelle, die jaenicke meinte, einen Zugriff außerhalb der Arraygrenzen.
Solange das nicht zu einer Exception, Absturz etc führt, hast du einfach falsche Werte, welche zu unerwünschten Ergebnissen führen können.


galagher - Fr 21.12.12 21:09

user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
Dein Array test ist aufjedenfall fest auf eine Länge von 256 Einträgen fixiert
Jetzt nicht mehr, das Array ist jetzt dynamisch - siehe oben!

user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
Solange das nicht zu einer Exception, Absturz etc führt, hast du einfach falsche Werte, welche zu unerwünschten Ergebnissen führen können.
Ja, zu einer falschen Bewertung! Wenn 0 bedeutet, dass zwei Strings völlig verschieden sind und 100, dass sie identisch sind, dann muss bei zwei Strings, die beide dasselbe Wort enthalten, Result jedenfalls > 0 sein!

Jetzt mit dynamischem Array scheint es ja zu klappen. Aber ist das Array so, wie ich es gemacht habe, auch richtig?