![]() |
Ganz ekelige Fehler in Verb. mit dyn. Arrays
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Leute!
Ich komme grad nicht ganz klar mit meinem kleinen Progrämmchen... Folgende Aufgabenstellung: Eine Menge von gleichen Münzen ist gegeben, und EINE dieser Münzen ist leichter als die anderen (Falschgeld). Es steht lediglich eine Waage ohne Gewichte zur Verfügung. Ziel: Mit möglichst wenig Aufwand (Wiege-Durchläufen) die falsche Münze herausbekommen. Bei meinem Ansatz verwende ich ein array of boolean, true für "echtes" Geld, und ein Eintrag false für die falsche Münze. Prinzip: Die Menge wird in zwei gleiche Haufen geteilt, und gewogen. Die leichtere der beiden wird erneut geteilt, und wieder verwogen und das so lange, bis nur noch 2 Münzen zu wiegen sind -> dann hat man sie (Eine Behandlung für ungerade Münzanzahl ist mit drin, kommt gleich etwas Code dazu) Das Prinzip funktioniert super-hervorragend, und ist wirklich schnell! Bei satten 1000 Münzen sind so nur 10 Wägungen nötig. Jetzt das AABBEERR... Mein Programm funktioniert so weit, aber es tauchen an unterschiedlichsten Stellen Zugriffsverletzungen auf, die ich mir beim besten Willen nicht erklären kann! Bei z.B. 50 Münzen in der Ausgangsmenge knallt's IMMER, aber bei Vielfachen von 50 gehts problemlos!?!? Dabei kommt dort die 50 ja durch das ständige Halbieren AUCH vor... ab > 8000 gibt's fast immer einen Fehler. Noch schöner: Starte ich das Programm nicht in der IDE, so bekomme ich nichtmal eine Fehlermeldung, sondern das Programm wird sofort einfach abgeschossen. Knallhart... hier etwas Code:
Delphi-Quellcode:
Eine Stelle, an der Fehler auftritt kann ich noch nicht mal angeben... mal wird erst gar keine angezeigt, und sonst ist es immer eine andere Zeile...
type
TArray = array of boolean; . . . procedure CopyArray(origin: TArray; var destination: TArray); var i: Integer; begin for i := 0 to High(origin) do destination[i] := origin[i]; end; function ArrayFirstHalf(arOriginal: TArray): TArray; var i, m: Integer; begin m := Length(arOriginal) div 2; SetLength(result, m); for i := 0 to m do result[i] := arOriginal[i]; end; function ArraySecondHalf(arOriginal: TArray): TArray; var i, m: Integer; begin m := Length(arOriginal) div 2; SetLength(result, m); for i := 0 to m do result[i] := arOriginal[i+m]; end; function SumTrueElements(arOriginal: TArray): Integer; var i: Integer; begin result := 0; for i := 0 to High(arOriginal) do if arOriginal[i] then inc(result); end; function GetFalseElement(ar: TArray): Integer; var buffer, isBuffered : boolean; arOriginal, bufArray1, bufArray2 : TArray; Weigh1, Weigh2 : Integer; begin result := 0; SetLength(arOriginal, Length(ar)); CopyArray(ar, arOriginal); buffer := false; isBuffered := false; // zu Beginn noch nix gesichert :) while Length(arOriginal) > 1 do begin inc(result); if Boolean(Length(arOriginal) mod 2) then // Wenn Element-Anzahl ungerade begin if not isBuffered then // Wenn KEIN Wert gesichert begin buffer := arOriginal[High(arOriginal)]; // Wert des letzten Elementes in 'buffer' sichern isBuffered := true; // Flag: Es IST ein Wert gesichert end else // Wenn ein Wert gesichert IST begin SetLength(arOriginal, Length(arOriginal)+1); // Array-Größe um 1 erhöhen arOriginal[High(arOriginal)] := buffer; // gesichertes Element an letzte Position schreiben isBuffered := false; // Flag: Es ist KEIN Wert gesichert end; end; SetLength(bufArray1, Length(arOriginal) div 2); SetLength(bufArray2, Length(arOriginal) div 2); CopyArray(ArrayFirstHalf(arOriginal), bufArray1); CopyArray(ArraySecondHalf(arOriginal), bufArray2); Weigh1 := SumTrueElements(bufArray1); Weigh2 := SumTrueElements(bufArray2); if (Weigh1 = Weigh2) and isBuffered then Exit; // Beide Mengen sind gleich schwer -> im Puffer ist gesuchtes Element! SetLength(arOriginal, Length(bufArray1)); if Weigh1 < Weigh2 then CopyArray(bufArray1, arOriginal) else if Weigh1 > Weigh2 then CopyArray(bufArray2, arOriginal); // Die "leichtere" Menge zur OriginalMenge machen end; // while-Schleife end; // Prozedur Wäre euch super-dankbar, wenn ihr mir etwas helfen könntet! dizzy Hier auch mal das Projekt: |
Re: Ganz ekelige Fehler in Verb. mit dyn. Arrays
ein Grund dürfte dies sein:
Delphi-Quellcode:
Annahme: m = 3 -> Array mit 3 Elemente, Index 0 bis 2
[..]
SetLength(result, m); for i := 0 to m do [..] Aber: 4 Schleifendurchläufe (0,1,2,3) beim letzen Durchgang wird willkürlich auf den Speicher nach dem Array zugegriffen... dies kann auf die Dauer nicht gutgehen.... Lösung:
Delphi-Quellcode:
for i:=1 to m do einArray[i - 1]...
|
Re: Ganz ekelige Fehler in Verb. mit dyn. Arrays
Ach du Sch****... Da sieht man den Wald vor lauter Bäumen nicht mehr, und dann so ein klassischer Fehler!! :pale:
Gaaanz heissen Dank!! Das war beim debuggen absolut nicht zo lokalisieren... Et lüppt! :bounce1: :dp:, ich wusste es |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz