ESternal:SIGSEGV - verkettete Liste mit TStringList

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Cephir
Beiträge: 3
Registriert: Fr 30. Nov 2012, 17:07

ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von Cephir »

Nach dem ich das Programm kompiliert habe kommt bei der Ausführung immer folgende Fehlermeldung:

http://www.bilder-hochladen.net/files/h ... pg-nb.html
Da oberer Link gerade nicht geht, siehe Dateianhang

Bild konnte ich nicht normal einfügen, da kommt immer die Meldung "Die Größe des Bildes konnte nicht ermittelt werden."

Das entsprechende Codestück:

Code: Alles auswählen

 
const Path = '"irgendein Pfad"';
 
Type
    TDataList     = ^RThreadList;
    RThreadList   = Record
                     Data : TStringList;
                     Next : TDataList;
                  end;
 
PROCEDURE DataLoop;
 
implementation
 
PROCEDURE DataLoop;
var
   dirinfo   : searchrec;
   PThreads   : DataList ;  
begin
   //Dateien laden
   New(PThreads);
   findfirst(Path + '*.*', AnyFile, dirinfo);
   while doserror = 0 do
   begin
       PThreads^.Data := TStringList.create;                       // Zeile 40 - anscheinend Kern des Problems
       PThreads^.Data.LoadFromFile(Path + dirinfo.name);
       PThreads := PThreads^.Next;
       findnext(dirinfo);
   end;
   findclose(dirinfo); 
 
{Rufe andere Prozedur zu Weiterverarbeitung auf...}
 
 
Wenn ich dies mit einer einzelnen Variablen mache, funktioniert es, aber sobald ich
eine verkettete Liste verwende, kommt die Fehlermeldung.
Dateianhänge
Fehlermeldung.jpg
Fehlermeldung.jpg (21.71 KiB) 1025 mal betrachtet
Zuletzt geändert von Cephir am Fr 30. Nov 2012, 18:15, insgesamt 3-mal geändert.

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von theo »

Nur mal so wegen der Lesbarkeit:

Nimm nicht den Namen TThread, die Klasse gibt es schon in classes.pas http://www.freepascal.org/docs-html/rtl ... hread.html
Das stiftet nur Verwirrung.

Dann fange die Benennung von Pointern mit P nicht T an. Also z.B. PMyThread dann liest es sich gleich flüssiger.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von Socke »

Cephir hat geschrieben:Wenn ich dies mit einer einzelnen Variablen mache, funktioniert es, aber sobald ich eine verkettete Liste verwende, kommt die Fehlermeldung.
Ist doch klar: der erste Record wird außerhalb der schleife angelegt. Alle weiteren Records der Liste werden aber überhaupt nicht angelegt. Im zweiten Schleifendurchlauf greift das Programm quasi zwangsläufig auf einen nicht reservierten Speicherbereich zu.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Cephir
Beiträge: 3
Registriert: Fr 30. Nov 2012, 17:07

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von Cephir »

Socke hat geschrieben: Ist doch klar: der erste Record wird außerhalb der schleife angelegt. Alle weiteren Records der Liste werden aber überhaupt nicht angelegt. Im zweiten Schleifendurchlauf greift das Programm quasi zwangsläufig auf einen nicht reservierten Speicherbereich zu.
Und wie lässt sich dieses Problem lösen? Ich meine, das würde ja dann auch mit vergleichbaren Datenstrukuren nicht funktionieren.
AVL-Tree?

@theo: Ich ändere es gleich ab.

EDIT:
Und ich weise doch theoretisch immer wieder dem Data Element Speicher zu? Warum funktioniert das nicht?

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von Socke »

Cephir hat geschrieben:
Socke hat geschrieben: Ist doch klar: der erste Record wird außerhalb der schleife angelegt. Alle weiteren Records der Liste werden aber überhaupt nicht angelegt. Im zweiten Schleifendurchlauf greift das Programm quasi zwangsläufig auf einen nicht reservierten Speicherbereich zu.
Und wie lässt sich dieses Problem lösen? Ich meine, das würde ja dann auch mit vergleichbaren Datenstrukuren nicht funktionieren.
Was meinst du mit vergleichbar? Das einzige, was ich mit einem Record vergleiche, ist ein Record. In deinem Fall ist nicht die Stringliste Schuld an der Ausnahme sondern der Zugriff auf ein uninitialisiertes PThreads^ im zweiten (und jedem theoretisch nachfolgenden) Schleifendurchlauf.

Zur Lösung: In jedem Schleifendurchlauf muss ein neuer Record erzeugt werden. Ein Zeiger Darauf muss im Element Next des vorhergehenden Knotens gespeichert werden. Im letzten Knoten wird Next auf nil gesetzt um anzuzeigen, dass keine weiteren Elemente folgen.

Code: Alles auswählen

A -> B -> C -> nil
Visualisierung einer verketteten Liste. Bei deinem Code wird A vor der Schleife initialisiert und in der Schleife mit Daten gefüllt. Danach wird dein Positionszeiger auf A.Next gesetzt. A.Next ist uninitialisiert und enthält daher keine gültige Adresse eines Records.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Cephir
Beiträge: 3
Registriert: Fr 30. Nov 2012, 17:07

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von Cephir »

Socke hat geschrieben: Was meinst du mit vergleichbar?

Ich meinte eigentlich mit Zeigern verkettete Strukuren, wie Listen und Bäume.
Aber da liege ich falsch, wie ich nach deiner Aufklärung sehe.
Socke hat geschrieben: Zur Lösung: In jedem Schleifendurchlauf muss ein neuer Record erzeugt werden. Ein Zeiger Darauf muss im Element Next des vorhergehenden Knotens gespeichert werden. Im letzten Knoten wird Next auf nil gesetzt um anzuzeigen, dass keine weiteren Elemente folgen.

Code: Alles auswählen

A -> B -> C -> nil
Visualisierung einer verketteten Liste. Bei deinem Code wird A vor der Schleife initialisiert und in der Schleife mit Daten gefüllt. Danach wird dein Positionszeiger auf A.Next gesetzt. A.Next ist uninitialisiert und enthält daher keine gültige Adresse eines Records.
Vielen Dank, auch wenn die Lösung so einfach war, wie befürchtet.
Ich habe mir nun auch schnell mal die alten Programme aus dem Informatikunterricht angeschaut, da habe ich es genauso gemacht, wie du geschrieben hast - warum kam ich nicht schon vorher darauf, dort nachzuschauen *grumel*?
Das kommt davon, wenn man nach 1,5 Jahren und ca. 30% Restwissen wieder anfängt.
Dann mal schauen, ob jetzt alles funktioniert.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von Socke »

Cephir hat geschrieben:Das kommt davon, wenn man nach 1,5 Jahren und ca. 30% Restwissen wieder anfängt.
Dann kommen die restlichen 90 % auch wieder von ganz alleine hoch. Meine Erfahrung war, dass der Informatikunterricht bei weitem nicht das abdeckt, was eine Programmiersprache bietet. Allenfalls werden einige allgemeine Vorgehensweisen, Muster und Strukturen gelehrt.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2813
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: ESternal:SIGSEGV - verkettete Liste mit TStringList

Beitrag von m.fuchs »

Socke hat geschrieben:
Cephir hat geschrieben:... und ca. 30% Restwissen wieder anfängt.
Dann kommen die restlichen 90 % auch wieder von ganz alleine ...
Interessante Rechnung... :mrgreen:

SCNR
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten