2011-01-11 29 views
0

Ich bin fassungslos, warum gibt mir dieser Code einen Segmentierungsfehler?Warum ergibt dies einen Segmentierungsfehler?

#include <stdio.h> 

#define LIMIT 1500000 

typedef struct { 
    int p; 
    int a; 
    int b; 
} triplet; 

int main(int argc, char **argv) { 
    int i; 
    triplet triplets[LIMIT]; 

    for (i = 0; i < LIMIT; i++) { 
     triplets[i].p = 9; // remove this line and everything works fine 
    } 

    printf("%d\n", triplets[15].p); 

    return 0; 
} 

EDIT: Nach LIMIT 150 Ändern bekomme ich nicht mehr einen Segmentation Fault, druckt er Zufallszahlen statt.

EDIT2: Jetzt weiß ich, was der Name der Seite steht :) Ich machte das Array global und alles funktioniert jetzt gut.

+1

Die Zahlen sind alles, was auf dem Stapel passiert sein (da Sie nur die ersten fünf Feldelemente initialisiert sind, aber Sie drucken den 16.) . – Shog9

+0

'Es druckt stattdessen Zufallszahlen.' Was drucken Sie eigentlich? Zeigen Sie den gesamten Code. – Mahesh

+0

@Mahesh: Bitte lesen Sie die letzten drei Zeilen. – orlp

Antwort

10

Stapelüberlauf! Die Zuweisung von 1500000 Datensätzen zu 12 Byte pro Datensatz (unter der Annahme von 4 Byte int) erfordert mehr als 17 MB Stapelspeicher. Machen Sie Ihr triplets Array global oder ordnen Sie es dynamisch zu.

In Bezug auf Ihre bearbeiten - das Array schrumpfen wird wahrscheinlich die Stack-Überlauf stoppen, aber Ihre printf() Anruf wird noch nicht initialisierte Daten drucken - triplets[15].p konnte etwas zu der Zeit Sie es ausdrucken sein.

+0

Ich bin nicht gut mit C, wie würde ich den Code ändern, um dies zu vermeiden? – orlp

+0

Nicht zu vergessen, dass Sie versuchen, auf nicht initialisierten Speicher zuzugreifen. Stellen Sie sicher, dass Sie "triplets [15] .p" etwas zuweisen, bevor Sie versuchen, es zu lesen. –

+0

Die Linie, die mir den Ärger machte, war die Zeile, in der ich alles initialisieren wollte. Aber ich habe einen schönen Segmentierungsfehler bekommen. Das <5 in der for-Schleife war ein zufälliger Test von mir. – orlp

4

Wenn Sie das tun

triplet triplets[LIMIT]; 

Sie Zuweisen, dass auf dem Stapel. Das ist anscheinend zu groß für Ihr System.

Wenn Sie

triplet* triplets=(triplet*)malloc(LIMIT*sizeof(triplet)); 

tun zuteilen Sie es auf dem Heap und alles sollte in Ordnung sein. Achten Sie darauf, um den Speicher freizugeben, wenn Sie mit ihm fertig sind

free(triplets); 
+0

Beachten Sie, dass das OP auch Geltungsbereich beibehalten und im Datensegment statt Stack zuweisen konnte, indem Sie die Array-Deklaration zu 'statischen Triplet Triplets [LIMIT]; ist wahrscheinlich eine bessere Option, als es zu einem öffentlichen globalen zu machen. Die Lösung "malloc()" ist jedoch auf lange Sicht wahrscheinlich der bessere Ansatz. – RBerteig

+1

Es ist auch nicht notwendig, den malloc-Rückgabetyp in C zu konvertieren. Http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc –

Verwandte Themen