External: SIGSEGV bei Showmessage(inttostr(i));

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
DOS
Beiträge: 18
Registriert: Mi 13. Dez 2017, 21:04
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von DOS »

Moin,

ich versuche gerade ein Projekt in Lazarus zu verwirklichen, ich arbeite Ursprünglich mit Basic, weshalb mich einige Meldungen doch sehr verwirren bei Lazarus.

Aktuelle erhalte ich die Meldung External: SIGSEGV und ich kann mir keinen Reim darauf machen, wieso diese Meldung genau kommt, denn bis auf das mir am ende ASM Code angezeigt wird, sagt mir der Debugger nicht wirklich was aus.

Ich will eigentlich versuchen Buchstabe für Buchstabe durch zu gehen, um das Array neu zu sortieren, das Funktioniert nicht wirklich, daher wollte ich schauen wo es hängt und mir anschauen wo I jeweils genau was macht, aber schon die Zeile Showmessage(inttostr(i)); löst den Fehler aus, nehm ich ihn weg, läuft das Programm, sortiert nur nix, kopiert aber die daten vom einem Array ins andere.

Kann mir ggf. jemand auf die Sprünge Helfen wieso genau das Ausgelöst wird?

Code: Alles auswählen

procedure loadKD();
var
   k_IdS: Array Of String;
   k_NNameS: Array Of String;
   k_VNameS: Array Of String;
   k_StrasseS: Array Of String;
   k,i,t: integer;
   caS: Integer;
begin
    loadKDB();       // Lade KD(Unit 2)

    SetLength(k_IdS,k_Count+1);
    SetLength(k_NNameS,k_Count+1);
    SetLength(k_VNameS,k_Count+1);
    SetLength(k_StrasseS,k_Count+1);

    // Sortieren nach alphabet
    caS:= 65;
    For i := caS To (caS + 25) do
       begin                              // Alphabet durchgehen.
            For t := 0 to k_Count do
               begin
                  IF AnsiUpperCase(AnsiLeftStr(k_NName[t],1)) = char(i) then
                     begin
                        showmessage(inttostr(i));
                        k_IdS[t] := k_Id[t];
                        k_NNameS[t] := k_NName[t];
                        k_VNameS[t] := k_VName[t];
                        k_StrasseS[t] := k_Strasse[t];
                     end;
               end;
       end;

    Form2.elb.RowCount := k_Count + 1; // Anzahl der Zeilen setzen + 1
    Form2.elb.cells[0,0] := 'ID';
    Form2.elb.ColWidths[0] := 50;
    Form2.elb.cells[1,0] := 'Vorname';
    Form2.elb.ColWidths[1] := 140;
    Form2.elb.cells[2,0] := 'Nachname';
    Form2.elb.ColWidths[2] := 140;
    Form2.elb.cells[3,0] := 'Straße';
    Form2.elb.ColWidths[3] := 145;

    for k := 1 to k_Count do
       begin
       Form2.elb.cells[0,k] := k_IdS[k];
       Form2.elb.cells[1,k] := k_VNameS[k];
       Form2.elb.cells[2,k] := k_NNameS[k];
       Form2.elb.cells[3,k] := k_StrasseS[k];
       end;
end;  

hum4n0id3
Beiträge: 301
Registriert: So 5. Mai 2019, 15:23

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von hum4n0id3 »

Habe Quatsch geschrieben. Sorry.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 169
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von Jorg3000 »

Hi!
Deinen Codeausschnitt kann ich bei mir nicht kompilieren, weil k_NName darin nicht definiert ist.
Ich vermute, dass hier auch das Problem sein könnte: In der Zeile ...

Code: Alles auswählen

IF AnsiUpperCase(AnsiLeftStr(k_NName[t],1)) = char(i) then
... greifst du auf k_NName[t] zu, aber vielleicht hat k_NName gar keine ausreichende Länge für Index [t] ?
Dann könnte es zu dem SIGSEGV-Fehler kommen, weil der Zugriff auf den nicht reservierten Speicher unzulässig ist.
Grüße, Jörg

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

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von theo »

Schalte doch mal bei:
Projekt -> Projekteinstellungen -> Debuggen -> Bereich (-Cr) ein, dann bekommst du vielleicht informativere Fehlermeldungen.

Benutzeravatar
six1
Beiträge: 788
Registriert: Do 1. Jul 2010, 19:01

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von six1 »

das hier:
for k := 1 to k_Count do

geht schief, weil du an dieser Stelle mit der "1" Basis arbeitest. Arrays sind aber "0" basierender Index!

also wäre richtig:
for k := 0 to k_Count-1 do
Gruß, Michael

DOS
Beiträge: 18
Registriert: Mi 13. Dez 2017, 21:04
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von DOS »

Jorg3000 hat geschrieben:
Do 16. Jun 2022, 08:23
Hi!
Deinen Codeausschnitt kann ich bei mir nicht kompilieren, weil k_NName darin nicht definiert ist.
Ich vermute, dass hier auch das Problem sein könnte: In der Zeile ...

Code: Alles auswählen

IF AnsiUpperCase(AnsiLeftStr(k_NName[t],1)) = char(i) then
... greifst du auf k_NName[t] zu, aber vielleicht hat k_NName gar keine ausreichende Länge für Index [t] ?
Dann könnte es zu dem SIGSEGV-Fehler kommen, weil der Zugriff auf den nicht reservierten Speicher unzulässig ist.
Grüße, Jörg
In Unit2 zähle ich den bedarf und setze das Araay ja mit SetLength(k_NNameS,k_Count+1) auf die passende Länge und lasse mir zusätzlich 1 Platz mehr. Ich weiss auch nicht mehr genau wann SIDSEGV dazu kam, gefüht war es ohne Grund einfach da.
six1 hat geschrieben:
Do 16. Jun 2022, 10:01
das hier:
for k := 1 to k_Count do

geht schief, weil du an dieser Stelle mit der "1" Basis arbeitest. Arrays sind aber "0" basierender Index!

also wäre richtig:
for k := 0 to k_Count-1 do
Naja aber ob ich den ersten Array Eintrag ignoriere oder nicht, sollte keine Rolle Spielen ob ich mit dem ersten Eintrag oder dem Zweiten Eintrag anfange. Wäre mir zumindest neu, ich könnte zumindest in Basic auch ne For Next Schleife mit 10 Anfangen wenn ich bis 100 Will zum Beispiel.
theo hat geschrieben:
Do 16. Jun 2022, 09:45
Schalte doch mal bei:
Projekt -> Projekteinstellungen -> Debuggen -> Bereich (-Cr) ein, dann bekommst du vielleicht informativere Fehlermeldungen.
Jau, das hat zumindest neue Infos gegeben. Jetzt kommt die Meldung: Exception-Klass >> RunError(201) << ausgelöst mit der Meldung:
In Datei Unit3.pas Zeile 173
Form2.elb.cells[0,k] := k_IdS[k];

Interessanterweise zeigt er mir jetzt die ausgabe von Showmessage an.

Benutzeravatar
six1
Beiträge: 788
Registriert: Do 1. Jul 2010, 19:01

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von six1 »

Naja aber ob ich den ersten Array Eintrag ignoriere oder nicht, sollte keine Rolle Spielen ob ich mit dem ersten Eintrag oder dem Zweiten Eintrag anfange. Wäre mir zumindest neu, ich könnte zumindest in Basic auch ne For Next Schleife mit 10 Anfangen wenn ich bis 100 Will zum Beispiel.
beim ersten Eintrag ist es nicht so schlimm, wenn du 2 Einträge im Array hast... der letzte führt zu einer Exception bei deiner Zählweise!
Gruß, Michael

DOS
Beiträge: 18
Registriert: Mi 13. Dez 2017, 21:04
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von DOS »

six1 hat geschrieben:
Do 16. Jun 2022, 15:38
Naja aber ob ich den ersten Array Eintrag ignoriere oder nicht, sollte keine Rolle Spielen ob ich mit dem ersten Eintrag oder dem Zweiten Eintrag anfange. Wäre mir zumindest neu, ich könnte zumindest in Basic auch ne For Next Schleife mit 10 Anfangen wenn ich bis 100 Will zum Beispiel.
beim ersten Eintrag ist es nicht so schlimm, wenn du 2 Einträge im Array hast... der letzte führt zu einer Exception bei deiner Zählweise!
Ok dann hab ich einen Denkfehler. Ich setze die Länge des Arrays mit k_Count+1 eins höher als nötig. Ich fange zwar erst von 1 an zu zählen, weil der erste Eintrag nicht benötigt wird, zähle aber nur bis k_Count also einen unter der Array Grenze. Oder sehe ich das gerade falsch?

Benutzeravatar
six1
Beiträge: 788
Registriert: Do 1. Jul 2010, 19:01

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von six1 »

ja, siehst du falsch.
den letzten Eintrag eines Array kannst du mit high(array) heraus bekommen.

Ein Array mit 10 Einträgen hat als letzten Index 9 !

Du kannst auch folgendes machen:
SetLength(k_IdS,high(k_IdS)+2);

maxc := high(k_IdS);
oder direkt
for k := 0 to high(k_IdS) do
Gruß, Michael

DOS
Beiträge: 18
Registriert: Mi 13. Dez 2017, 21:04
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von DOS »

Ok, ja dessen bin ich mir ja voll bewusst das von 0 - 9 gleich 10 entspricht.

Ok meine Denkweise dazu. Ich würd da jetzt gerne meinen Denkfehler verstehen.

Nehmen wir als Beispiel mal an k_Count hat wirklich 10, ich gebe noch eins dazu und wir hätten dann von 0 - 10. Ich lasse von 1 Zählen und gehe bis k_Count also 9. dann ist mit 10 Real aber immer noch einer mehr da als es benötigt wird, denn For zählt ja nur 9 schritte weit. 11 könnten gesamt gemacht werden wenn z.B.: wirklich von 0 an gezählt wird. oder halt 10 wenn von 1 wie ich es mache und nicht von 0 an gezählt werden.

Benutzeravatar
six1
Beiträge: 788
Registriert: Do 1. Jul 2010, 19:01

Re: External: SIGSEGV bei Showmessage(inttostr(i));

Beitrag von six1 »

Also grundsätzlich ziehe ich nie eine Zählvariable mit bei dynamischen Arrays!
Schleifen lasse ich von 0 bis high(array) laufen. Das stimmt dann ganz genau :)

Lasse dein Array doch mal zwei Elemente groß sein und gehe Step by Step mit dem Debuger durch. Du wirst dann ganz genau sehen, wo du auf einen ungültigen Index zugreifst.
Gruß, Michael

Antworten