AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Ganz ekelige Fehler in Verb. mit dyn. Arrays
Thema durchsuchen
Ansicht
Themen-Optionen

Ganz ekelige Fehler in Verb. mit dyn. Arrays

Ein Thema von dizzy · begonnen am 24. Mär 2004 · letzter Beitrag vom 24. Mär 2004
Antwort Antwort
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#1

Ganz ekelige Fehler in Verb. mit dyn. Arrays

  Alt 24. Mär 2004, 19:07
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:
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
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...

Wäre euch super-dankbar, wenn ihr mir etwas helfen könntet!
dizzy

Hier auch mal das Projekt:
Angehängte Dateien
Dateityp: zip project1_214.zip (239,7 KB, 1x aufgerufen)
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#2

Re: Ganz ekelige Fehler in Verb. mit dyn. Arrays

  Alt 24. Mär 2004, 19:15
ein Grund dürfte dies sein:

Delphi-Quellcode:
[..]
SetLength(result, m);
for i := 0 to m do
[..]
Annahme: m = 3 -> Array mit 3 Elemente, Index 0 bis 2
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:
for i:=1 to m do einArray[i - 1]...
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Ganz ekelige Fehler in Verb. mit dyn. Arrays

  Alt 24. Mär 2004, 19:26
Ach du Sch****... Da sieht man den Wald vor lauter Bäumen nicht mehr, und dann so ein klassischer Fehler!!

Gaaanz heissen Dank!! Das war beim debuggen absolut nicht zo lokalisieren... Et lüppt!



, ich wusste es
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz