Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Programmabsturz durch einfügen eines TButton ??[Beantwortet] (https://www.delphipraxis.net/115141-programmabsturz-durch-einfuegen-eines-tbutton-%5Bbeantwortet%5D.html)

Corpsman 6. Jun 2008 16:41


Programmabsturz durch einfügen eines TButton ??[Beantwortet]
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

ich hab hier ein Phänomen das ich nicht verstehe.

Anbei der von mir erstellte Code.

ihr könnt die Exe starten und auf den Button klicken , und seht die Korreckt Fouriertransformierte der Eingabedaten.

Wenn man nun hergeht und in der IDE ( bei mir Delphi5 Pro )

einen Tbutton auf das Formular zieht.

Neu kompiliert und dann wieder auf Button1 klickt, kommt nur noch Müll nach der Transformierten heraus.

aber wieso ?

Der Code hat sich ja ansich nicht geändert.

Kann mir jemand von euch erklären was da falsch gelaufen ist ?

Fussball-Robby 6. Jun 2008 16:51

Re: Programmabsturz durch einfügen eines TButton ??
 
Die Exe funktioniert bei mir, beim kompilieren (D7 E) gibts allerdings eine AV beim Aufruf der Prozedur fftwf_execute :? Setze ich dann aber noch einen TButton auf die Form, gibts an der Stelle keinen Fehler, aber bei fftwf_destroy_plan einen EInvalidPointer-Fehler. Entferne ich den Button wieder, kommt, genau wie vorher, die AV.
Komisch :gruebel:

shmia 6. Jun 2008 17:08

Re: Programmabsturz durch einfügen eines TButton ??
 
Also entweder hat die DLL einen Bug oder du steuerst die DLL falsch an.
In beiden Fällen überschreibt die DLL irgendwo Speicher.
Dadurch, dass du einen Button einfügst verschiebt sich das Speicherlayout geringfügig.
Nun hängt es von den äusseren Umständen ab, ob die Speicherüberschreibung zu einem Fehler führt oder nicht.

Was tun?
a.) eine FFT-Unit in Pascal besorgen und benützen
b.) Anleitung für die DLL genauestens studieren und besonders darauf achten, WER muss Speicher bereitstellen und wer gibt ihn wieder frei.

Wenn die DLL ausser FFT keine besonderen Features hat, würde ich Variante a.) versuchen.

Medium 6. Jun 2008 17:15

Re: Programmabsturz durch einfügen eines TButton ??
 
Du hast 2 Probleme:

Delphi-Quellcode:
  plan := fftwf_plan_dft_1d(n, @In_[0], @Out_[0], FFTW_FORWARD, FFTW_ESTIMATE);
  With canvas Do Begin
    fftwf_execute(plan);

    plan := fftwf_plan_dft_1d(n, @Out_[0], @in_[0],
      FFTW_Backward, FFTW_ESTIMATE);
  fftwf_destroy_plan(plan);
Nimmt man den ganzen Zeichenkram mal weg sieht man schon mal: Du erstellst einen Plan, führst ihn aus, erstellst einen neuen (ohne den alten zu löschen), löscht aber den neuen zum Schluss. Folge: Speicherloch.
Zumal das Einschließen des Executes und das Erzeugen den 2. Plans in das with hier zur Unübersichtlichkeit beitragen.


Was aber letztlich vermute ich das Problem ist, ist dass die FFTW beim Erstellen eines Plans (wenn man es nicht explizit angibt) nicht dafür garantiert, dass die Werte in den Arrays beibehalten werden! Der Plan kann aber auch problemlos mit 0-besetzten Arrays gemacht werden, und das Füllen nachher. Es geht eh nur um die Samplemenge. Für die Rücktransformation müsstest du dir entweder das Array selbst zwischenspeichern, oder aber schauen wie man der FFTW sagen kann, dass es die Arrays in Ruhe lassen soll (ich meine das ging, weiss aber gerade nicht mehr wie).

Zum Schluss könnte dir das Alignment noch ans Bein pullern. Mach aus den Arrays mal packed Arrays.

Corpsman 6. Jun 2008 18:08

Re: Programmabsturz durch einfügen eines TButton ??
 
also, die übersichtlichkeit und die Leaks waren mir bisher Egal weil das ja ein dirty sample war.

aber selbst wenn ich Button1.onclick zu

Delphi-Quellcode:
Procedure TForm1.Button1Click(Sender: TObject);
Var
  in_, Out_: Array Of single;
  plan: Pointer;
  //  plan2: Pointer;
  i, n: Integer;
Begin
  With canvas Do Begin
    n := 256;
    SetLength(In_, N);
    SetLength(Out_, N);

    plan := fftwf_plan_dft_1d(n, @In_[0], @Out_[0], FFTW_FORWARD, FFTW_ESTIMATE);
    //    plan2 := fftwf_plan_dft_1d(n, @Out_[0], @in_[0], FFTW_Backward, FFTW_ESTIMATE);

    For i := 0 To n - 1 Do Begin
      in_[i] := 0;
      out_[i] := 0;
    End;

    For i := 64 - 12 To 64 + 11 Do
      in_[i] := 10;

    pen.color := clblack;

    fftwf_execute(plan);

    moveto(10 + 200, 150);
    For i := 0 To n - 1 Do Begin
      lineto(10 + i + 200, round(150 - in_[i]));
    End;
    moveto(10 + 200, 250);
    For i := 0 To n - 1 Do Begin
      lineto(10 + i + 200, round(250 - Out_[i] / sqrt(n)));
    End;
    //    fftwf_execute(plan2);
    moveto(10 + 200, 350);
    For i := 0 To n - 1 Do Begin
      lineto(10 + i + 200, round(350 - in_[i]));
    End;
    //    fftwf_destroy_plan(plan2);
    fftwf_destroy_plan(plan);
  End;
End;
Umbaue bleibt der Fehler :(

das es an fftw liegt scheint mir unwahrscheinlich, da die ja zig fach veröffentlicht ist und Fehler bis dahin gefunden wären ..

die saceh mit dem packed bringt übrigens auch nichts ..

Medium 6. Jun 2008 18:38

Re: Programmabsturz durch einfügen eines TButton ??
 
Ähhhm Sekunde mal! Deine Arrays sind zu klein. Die FFTW erwartet folgendes:
Delphi-Quellcode:
type
  TComplex = packed record
    Re, Im: Double;

  TComplexArray = packed array of TComplex;
.
.
.
plan := fftwf_plan_dft_1d(n, @In_[0].Re, @Out_[0].Re, FFTW_FORWARD, FFTW_ESTIMATE);
AUSSER(!) Du verwendest die Versionen die speziell für rein Reellwertige Samples gedacht sind. Dort wird dann bei Forward ein array of Double erwartet wie du es hast, und als Out-Array ein array of TComplex, das aber nur halb so lang ist. (Bei Rücktransformation entprechend anders herum.)

Edit: Du kannst auch einfach ein array of Double nehmen, und jeden 2. Wert als Imaginäranteil "von Hand" interpretieren. Es muss halt nur doppelt so lang sein wie N angibt.

Edit2...: In der FFTW Doku gibts imho auch eine Übersicht, wie die Arrays ganz detailiert auszusehen haben, und wo die Unterschiede in den verschiedenen Funktionsaufrufen und Betriebsmodi liegen. Das ist zugegebenermaßen erstmal fummelig, dafür haben sich die Jungs echt Gedanken gemacht.

Edit3: Letztes Edit. Rechtschreibung und so. :stupid:

Corpsman 6. Jun 2008 20:43

Re: Programmabsturz durch einfügen eines TButton ??
 
ich war zu langsam, aber bin nu auch aufMediums lösung gekommen

Delphi-Quellcode:
Type
  blub = Record
    real: single;
    imag: single;
  End;

Var
  in_, Out_: Array Of blub;
mit Hilfe der unit Memcheck konnte man den Fehler entdecken.

Der Fehler war einfach das in der Umwandlungsunit PSingle stand und das nirgens definiert war. Ich ging da einfach von falschen tatsachen aus.

thx für eure Hilfe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:21 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