Ah ha! Dein Problem ensteht in Peak_n_Valley: du nimmst die TSignalPoint Instanzen aus ts.Signal und fügst die in dein Result ein. Dieses gibst du dann in ProcessTimeSeries wieder frei und damit werden dann auch alle TSignalPoint Instanzen dort freigegeben was dann dazu führt, dass es beim Freigeben der Einträge in BoltTLS knallt. Du musst entweder neue TSignalPoint Instanzen anlegen (zum Beispiel über einen weiteren Konstruktor, der einen existierenden TSignalPoint annimmt und dann alle Felder kopiert) oder falls du es in der TTimeSeries nicht mehr brauchst über Extract herausnehmen ohne dass es freigegeben wird.photor hat geschrieben: So 21. Mär 2021, 17:13 Dann noch der Code zu:Diese Prozedure sucht (im Moment nur nach Minima und Maxima in der übergebenen (einzelnen) TimeSeries, speichert die entsprechenden Signal-Zeitpunkte in einer neuen TimeSeries TS_minmax, die dann gespeichert wird. Zum Schluss wird die TS_minmax freigegeben (im weiteren Verlauf soll hier natürlich noch mehr mit passieren - also müsste ich die eigentlich auch wieder als Ergebnis zurück geben; das war aber für jetzt zu kompliziert).Code: Alles auswählen
procedure TMainForm.ProcessTimeSeries(ts: TTimeSeries); var fname: string; TS_minmax: TTimeSeries; begin try // find min/max TS_minmax := Peak_n_Valley(ts); fname := TS_minmax.Name + '.txt'; TS_minmax.SaveToFile(fname); finally TS_minmax.Free; end; end;
... und dann noch (in einer eigenen Unit sb_defs.pas):Code: Alles auswählen
function Peak_n_Valley(ts: TTimeSeries) : TTimeSeries; var i: integer; spu, sp, spo: TSignalPoint; begin result := TTimeSeries.Create; // add 1st data point to list sp := ts.Signal.First; result.Signal.Add(sp); // look for relative min and max in time series for i:=1 to ts.Signal.Count-2 do begin spu := ts.Signal.Items[i-1]; sp := ts.Signal.Items[i]; spo := ts.Signal.Items[i+1]; if is_minmax(spu, sp, spo) then result.Signal.Add(sp); end; // add last data point sp := ts.Signal.Last; result.Signal.Add(sp); result.Name := ts.Name; // set number of entries in resulting TimeSeries result.NoEntries := result.Signal.Count; end; function is_minmax(dpu, dp, dpo: TSignalPoint): boolean; var diff1, diff2: double; begin result := false; diff1 := dp.Value - dpu.Value; diff2 := dpo.Value - dp.Value; if (((diff1 > 0.0) and (diff2 < 0.0)) or // rel. maximum ((diff1 < 0.0) and (diff2 > 0.0))) then // rel. minimum result := true end;
SIGSEGV beim Freigeben von Klasse
-
- Beiträge: 955
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: SIGSEGV beim Freigeben von Klasse
FPC Compiler Entwickler
- photor
- Beiträge: 512
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: SIGSEGV beim Freigeben von Klasse
Moin,
Ah! Wenn Du das so erklärst, klingt das logisch. Danke. Da habe ich gerade was verstanden und was gelernt!
Ich glaube, ich hätte da noch lange gesucht.
Ciao,
Photor
Ah! Wenn Du das so erklärst, klingt das logisch. Danke. Da habe ich gerade was verstanden und was gelernt!
Ich glaube, ich hätte da noch lange gesucht.
Ciao,
Photor
-
- Beiträge: 2122
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: SIGSEGV beim Freigeben von Klasse
Noch eine alternative, TObjectList bekommt im Kosntruktor soweit ich weiß einen Boolean (OwnsObjects oder so), wenn du eine Liste haben willst die die elemente nicht löscht wenn sie freigegeben wird einfach mit False erstellen. Somit kannst du den selben Listen typen benutzen mit und ohne Freigabe mechanismus
- photor
- Beiträge: 512
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: SIGSEGV beim Freigeben von Klasse
Moin,
darüber habe ich auch schon nachgedacht. entweder bei TObjectList OwnsElements = False setzen oder TList nutzen. Das macht es aber am Ende schwieriger, alles aufzuräumen, richtig?
Ich probiere es zunächst mit dem Neuerzeugen der Elemente in der neuen Liste (ist etwas umständlich und unelegant). Alternativ könnte man in der Originalliste alles raus werfen, was man nicht braucht - widerstrebt mir aber im Moment noch.
PS: auch wenn das gerade nicht mehr nötig ist, wollte ich doch auch versuchen, Valgrind als Debugger an's Rennen zu bekommen. Das ist aber ein neues Thema.
Ciao,
Photor
darüber habe ich auch schon nachgedacht. entweder bei TObjectList OwnsElements = False setzen oder TList nutzen. Das macht es aber am Ende schwieriger, alles aufzuräumen, richtig?
Ich probiere es zunächst mit dem Neuerzeugen der Elemente in der neuen Liste (ist etwas umständlich und unelegant). Alternativ könnte man in der Originalliste alles raus werfen, was man nicht braucht - widerstrebt mir aber im Moment noch.
PS: auch wenn das gerade nicht mehr nötig ist, wollte ich doch auch versuchen, Valgrind als Debugger an's Rennen zu bekommen. Das ist aber ein neues Thema.
Ciao,
Photor