Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Stack Overflow (https://www.delphipraxis.net/115538-stack-overflow.html)

evilhomer 13. Jun 2008 16:23


Stack Overflow
 
Hi!

Ich bin gerade dabei einen Algorithmus zu erstellen, der beliebig viele der ersten Primzahlen rekursiv berechnet. Für mich erscheint der Code logisch, Abbruchbedingungen sind auch definiert, trotzdem beklagt sich Delphi über einen StackOverflow. Der Code sieht folgendermaßen aus:

Delphi-Quellcode:
procedure TForm1.Prim_re(n,i:integer);

begin
if (n < limit) then begin
       if (i<=1) then List2.Items.Add(IntToStr(n))
       else
         if (n mod i) <> 0 then Prim_re(n,i-1);
       end;
  Prim_re(n+1,n);
end;
Die Variable limit ist die Obergrenze, bis zu der Primzahlen gesucht und in der List2 angezeigt werden sollen. n steht für die aktuelle Zahl, die auf Teilbarkeit untersucht wird und i ist sozusagen eine Laufvariable.
An sich ist der Code also nicht allzu schwer zu durchblicken.
Ich hoffe dass irgendjemand mir helfen kann, bzw. weiß wo hier der Fehler liegen könnte?

Gruß und danke im Voraus

mkinzler 13. Jun 2008 16:26

Re: Stack Overflow
 
Lass dir mal n und i kontiniurlich anzeigen

evilhomer 13. Jun 2008 16:28

Re: Stack Overflow
 
Okay, wenn ich mir den Stack anschaue, dann zeigt er mir:

TForm1.Prim_re(2,???)
TForm1.Prim_re(3,???)
TForm1.Prim_re(4,???)
TForm1.Prim_re(5,???)

usw...
bloß, wie kommt es dazu?

mkinzler 13. Jun 2008 16:31

Re: Stack Overflow
 
Nirgends musst du selber machen

evilhomer 13. Jun 2008 16:36

Re: Stack Overflow
 
Gut, wenn ich den erneuten Aufruf

Delphi-Quellcode:
Prim_re(n+1,n);
auskommentiere, dann funktioniert es zumindest, aber das liefert mir natürlich nur eine Zahl, nicht die ganze Liste mit 100,200, wie vielen auch immer. Gibt es da einen Weg, die Funktion ohne Error aufzurufen? (Immerhin muss es rekursiv bleiben..)

FAlter 13. Jun 2008 16:47

Re: Stack Overflow
 
Hi,

der Code ist sehr eigenartig, hier einmal anders formatiert:

Delphi-Quellcode:
procedure TForm1.Prim_re(n,i:integer);
begin
  if (n < limit) then
  begin
    if (i<=1) then
      List2.Items.Add(IntToStr(n))
    else
    if (n mod i) <> 0 then
      Prim_re(n,i-1);
  end;

  Prim_re(n+1,n);
end;
Ich hoffe, jetzt wird die dein Fehler deutlich. Prim_re(n+1, n) wird IMMER aufgerufen, unabhängig davon, om n < limit.

Mfg
FAlter

NormanNG 13. Jun 2008 16:48

Re: Stack Overflow
 
Hi,

ich formatier deinen Quelltext mal etwas um:

Delphi-Quellcode:
procedure TForm1.Prim_re(n,i:integer);
begin
  if (n < limit) then
  begin
    if (i<=1) then
      List2.Items.Add(IntToStr(n))
    else
      if (n mod i) <> 0 then
        Prim_re(n,i-1);
  end;
  Prim_re(n+1,n);
end;
Jetzt siehtst du vielleicht, dass das mit der Abbruchbedingung noch nicht so ganz stimmt:
Egal, mit welchem N/I die Prozedur aufgerufen wird, sie sich ruft zuletzt immer wieder selbst auf.
Also nichts mit "Abbruch" ...

[edit]Upps, roter Kasten?[/edit]

shmia 13. Jun 2008 16:49

Re: Stack Overflow
 
Ich denke mal, der Fehler ist durch deine schlampige Einrückung entstanden.
Hier dein Code nach Borland Style Guide formatiert:
Delphi-Quellcode:
procedure TForm1.Prim_re(n,i:integer);
begin
  if n < limit then
  begin
    if i <= 1 then
      List2.Items.Add(IntToStr(n))
    else if (n mod i) <> 0 then
      Prim_re(n,i-1);
  end; // <== dieses end kommt zu früh
  Prim_re(n+1,n);  // <<== diese Zeile muss VOR das end
end;

evilhomer 13. Jun 2008 16:57

Re: Stack Overflow
 
Okay, das Problem hat sich nun erledigt. Der StackOverflow war ja schon beseitigt, und dass die Prozedur sich nur 1mal aufgerufen hat lag am "else if" statt "if"..
Wer den Code mal benötigen sollte, so funktioniert es bei mir:

Delphi-Quellcode:
procedure TForm1.Prim_re(n,i:integer);
var prim:boolean;

begin
  if n < limit then
  begin
    if i = 1 then List2.Items.Add(IntToStr(n));
    if (n mod i) = 0 then Prim_re(n+1,n)
    else Prim_re(n,i-1);
  end;
end;
Danke für eure Hilfe!

evilhomer 13. Jun 2008 17:12

Re: Stack Overflow
 
Sorry, so ganz ist das Problem immer noch nicht vom Tisch ...
Der Code sieht momentan so aus:

Delphi-Quellcode:
procedure TForm1.Prim_re(n,i:integer);
var prim:boolean;

begin
  if n < limit then
  begin
    if i = 1 then List2.Items.Add(IntToStr(n));
    if (n mod i) = 0 then Prim_re(n+1,n)
    else Prim_re(n,i-1);
  end;
end;
Funktioniert auch anscheinend wunderbar, solange man sich auf die Zahlen von 1 bis 293 beschränkt. Alles darüber bringt einen StackOverflow.
Aus irgendeinem Grund sieht der Stack so aus:

TForm1.Prim_re(???,???)
TForm1.Prim_re(293,2147350260)
TForm1.Prim_re(293,266)
TForm1.Prim_re(293,267)
TForm1.Prim_re(293,268)
... usw, usw

Wie kommt es dazu, dass der Speicher auf einmal so spinnt? Kennt sich vllt jemand damit aus?


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:28 Uhr.
Seite 1 von 2  1 2      

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-2025 by Thomas Breitkreuz