ubuntuusers.de

SIGSEGV Segmentation Fault

Status: Gelöst | Ubuntu-Version: Kubuntu 14.04 (Trusty Tahr)
Antworten |

belimatrix

Anmeldungsdatum:
20. Juli 2008

Beiträge: 49

Hallo, ich mache gerade meine ersten Schritte mit Qt und Qt Creator. Es gefällt mir auch. Beruflich "verheirate" ich inkompatible Datenbanksysteme mit c#, aber das nur so nebenbei 😉 Der unten dargestellte Algorithmus führt zum Programmabbruch mit dieser Fehlermeldung:

The inferior stopped because it received a signal from the Operating System.

Signal name : SIGSEGV Signal meaning : Segmentation fault

Der Abbruch erfolgt allerdings nur dann, wenn ich für int N einen Wert eingebe, der 2.100.000 oder größer ist. Der Wert wird aus einem QLineEdit bezogen und in Zeile 2 des Codeblocks zum int gewandelt. Beim Debuggen (und bei normalem Lauf) bricht das Programm (oder besser: Progrämmchen) in Zeile 4 ab mit der o.a. Fehlermeldung. Es entsteht der Eindruck, dass das Array mit 2.100.000 oder mehr Elementen vom Typ int zu groß für 16 GB RAM wäre. Das halte ich allerdings für ein Gerücht, denn da passt nachweislich mehr hinein.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
//Sieve of Eratosthenes
    int N = lneIntervalLimit->text().toInt();
    int i=0, j=0, a[N+1];
        for(a[1]=0, i=2; i<=N; i++) a[i]=1; ============>>> HIER KOMMT DER ABBRUCH
        for(i=2; i<=N/2; i++)
            if(a[i])
            for(j=i; j<= N/i; j++)
                a[i*j]=0;
        int k=0;
        for(i=1; i<=N; i++){

            if(a[i]) {
                result+=QString::number(i)+"\n";
                k++;
            }
        }

Falls Sieve of Eratosthenes unbekannt ist: Damit "fischt" man recht schnell alle Primzahlen von 2 bis (in meinem Fall) N. Das Progrämmchen sollte einer der ersten Versuche sein. Die Primzahlen sind dann auf Knopfdruck in QTextEdit untereinander zu sehen. k (Zeile 9) zählt die gefundenen Primzahlen und Zz. 10-14 "bauen" dann den Zahlenstring, der am Ende in die QTextEdit "hineingeworfen" wird. Das "Hineinwerfen" habe ich jedoch nicht mit zitiert.

Übrigens, mit C (C99-Standard und Konsolen-Anwendung) habe ich das gleiche Problem. Das führt wiederum zu der Annahme, dass es eher am Betriebssystem liegt als an mir oder der Programmiersprache bzw. Entwicklungsumgebung. Oder sind es doch Einstellungen des IDE?

Meine Frage wäre nun, ob jemand einen Weg kennt, diese Größenbegrenzung des des Arrays zu umgehen. Über die Ursachen finde ich im Netz ziemlich viel aber mein Fall ist leider nicht drin...

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

"Segmentation Fault" (= Speicherverletzung) ist doch typischerweise das Problem, wenn die deklarierten Grenzen von Variablen überschritten werden !?
(womöglich sowas ähnliches wie hier ?)

Ich bin nun zu wenig fit mit C / C++ um das direkt zu sehen, aber jedenfalls solltest Du mal in der Richtung suchen.

Edit: - guck Dir mal Deine Zeile 8 an ! - bist Du sicher, dass immer i² < N, also a[i²] definiert ist ?
- zudem hast Du die Schleife Z. 5-8 nicht geklammert.

LG,

track

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2505

Mit „int a[N]“ erzeugst du ein VLA und bei denen ist es wohl dem Compiler überlassen, wo er die Dinger allokiert. Die Wikipedia spricht davon, dass der GCC das auf dem Stack tut. Der Stack ist in seiner Größe üblicherweise beschränkt, bei mir sind’s zum Beispiel im Standardfall 8MB. „2'100'000 * sizeof (int)“ sind ca. 8MB und damit wahrscheinlich knapp über diesem Limit, wodurch es zum Absturz kommt.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

belimatrix schrieb:

Der Abbruch erfolgt allerdings nur dann, wenn ich für int N einen Wert eingebe, der 2.100.000 oder größer ist. Der Wert wird aus einem QLineEdit bezogen und in Zeile 2 des Codeblocks zum int gewandelt. Beim Debuggen (und bei normalem Lauf) bricht das Programm (oder besser: Progrämmchen) in Zeile 4 ab mit der o.a. Fehlermeldung. Es entsteht der Eindruck, dass das Array mit 2.100.000 oder mehr Elementen vom Typ int zu groß für 16 GB RAM wäre. Das halte ich allerdings für ein Gerücht, denn da passt nachweislich mehr hinein.

Dummerweise liegt aber a auf dem Stack. Und da ist bei weitem nicht so viel Platz. Bei mir z.B. 16MB:

1
2
$ ulimit -a | fgrep -i stack
stack size              (kbytes, -s) 16384

Solche Variablen gehören auf den Heap!

belimatrix

(Themenstarter)

Anmeldungsdatum:
20. Juli 2008

Beiträge: 49

rklm schrieb:

(...) Solche Variablen gehören auf den Heap!

OK. Das ist verstanden. WinzigWeich (MicroSoft) lässt einen etwas verkommen. ABER: Wie geht das mit'm Heap? Mein Stack bringt es auf 8 MB...

@track, so wie das Ding da steht, ist es schon richtig. Sieve von Eratosthenes ist nicht meine Erfindung, sie kommt aus der griechischen Antike. Ich habe sie nur abgetippt um das Textfenster zu füllen. Ich lerne noch.

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6488

Wohnort: Hamburg

ABER: Wie geht das mit'm Heap?

Ich habe mit Qt nichts am Hut, aber das klingt irgendwie nach C++ Unterbau. Daher könnte so etwas wie ein

a = new int [N+1];

helfen (bei C würde ich malloc() vorschlagen).

belimatrix

(Themenstarter)

Anmeldungsdatum:
20. Juli 2008

Beiträge: 49

Also... Der Tipp mit dem Heap war die Lösung. Zunächst half

1
ulimit -s unlimited

aber das kann nicht die Dauerlösung sein. Die korrekte, "heapgerechte" Array-Deklaration sieht so aus:

1
int *a = new int[N+1];

und es löwt 😉 Danke für eure Hilfe!

Antworten |