stack overflow bei fwrite/fread



  • Guten Tag,

    ich bekomme bei meinem Testprogramm den Fehler "Stack overflow".
    Kenn mich nicht so recht aus, irgendwie ist wohl der Puffer zu klein.
    Kann ich den vergrößern, bzw gibt es eine Möglichkeit das Pufferproblem zu umgeht?

    //Array füllen
    	unsigned int zahl[30][30][30][13];
        int ma, mb, mc;
    	for(ma=0; ma < 30; ma++) {
    		for(mb=0; mb < 30; mb++) {
    			for(mc=0; mc < 30; mc++) {
    				for (int i = 0; i < 13; i++) {
    					zahl[ma][mb][mc][i] = i;
    				}
    			}
    		}
    	}
    
       //schreiben
       FILE * schreibFile;
       schreibFile = fopen("bla.dat", "w+b");
       	for(ma=0; ma < 30; ma++) {
    		for(mb=0; mb < 30; mb++) {
    			for(mc=0; mc < 30; mc++) {
    				fwrite(zahl[ma][mb][mc], sizeof(unsigned int), 13, schreibFile);
    			}
    		}
       }
       fclose (schreibFile);
    
       //lesen
       unsigned int zahlkopie[30][30][30][13];
       FILE * leseFile;
       leseFile = fopen("bla.dat", "rb");
       for(ma=0; ma < 30; ma++) {
    		for(mb=0; mb < 30; mb++) {
    			for(mc=0; mc < 30; mc++) {
    				fread(zahlkopie[ma][mb][mc], sizeof(unsigned int), 13, leseFile);
    			}
    		}
       }
       fclose(leseFile);
    


  • Ich würde sagen, dein Array ist zu groß für den Stack. Das nimmt ca. 1,4MB in Anspruch, was zwar nicht viel ist, aber der Stack ist manchmal stark begrenzt.



  • Hmm, das ist ja sogar nur das Testprogramm, im richtigen soll das Array noch größer sein.

    Wie kann ich den Fehler "Stack overflow" vermeiden?



  • Schau dir malloc/free an.



  • Danke für deine Antwort.

    So wie ich das verstehe, verwende ich malloc um den Speicher dynamisch zu verwalten.
    Meine Arraygröße steht aber doch schon zu beginn fest.
    Wieso reserviert er sich den benötigten Speicher nicht automatisch?



  • kalli schrieb:

    Danke für deine Antwort.

    So wie ich das verstehe, verwende ich malloc um den Speicher dynamisch zu verwalten.
    Meine Arraygröße steht aber doch schon zu beginn fest.
    Wieso reserviert er sich den benötigten Speicher nicht automatisch?

    Weil der Stack zu klein ist. Nur deshalb. Eigentlich gehört das Array auf den Stack. Passt aber nicht.



  • Und den Stack auf den das Array gehört kann ich mit malloc vergrößern, oder wie?

    Sry raff das nicht so ganz, da fehlt mir wohl das Basiswissen.
    Wäre für einen Beispielcode sehr dankbar.



  • Der Stack ist für dein Programm immer fest, da kann man nichts "vergrößern".
    Ein Array kann man ebenso nicht vergrößern (erhält seine Größe bei Definition und bleibt dann IMMER UNVERÄNDERT).
    Du kannst zunächst mal versuchen, mit static ein andere Speicherklasse zu verwenden,

    static unsigned int zahl[30][30][30][13];
    

    ist aber ebenso häßlich wie zuvor, da auch der limitiert ist (meist aber größer als auto/Stack) UND du ebenfalls keine Abbruchprüfung in dein Programm einbauen kannst; hinzu kommt, dass der Speicher sich bei Mehrfachdefinition (in mehreren Funktionen) addiert und du u.U. wieder an das Limit stößt.

    Dynamischer Speicher löst all diese Probleme, und dabei free() nicht vergessen.

    http://ideone.com/pm3lPL

    int main(void) {
    	unsigned int a,b,c,d,(*p)[30][30][13];
    	p=calloc(30,sizeof*p);
    	if(!p)
    		perror("calloc"),exit(1);
    	for(a=0;a<30;a++)
    	for(b=0;b<30;b++)
    	for(c=0;c<30;c++)
    	for(d=0;d<13;d++)
    	p[a][b][c][d]=a*b*c*d;	
    
    	printf("%u %u",p[0][0][0][0],p[29][29][29][12]);
    
    	free(p);
    	return 0;
    }
    


  • Wutz schrieb:

    Du kannst zunächst mal versuchen, mit static ein andere Speicherklasse zu verwenden,

    static unsigned int zahl[30][30][30][13];
    

    ist aber ebenso häßlich wie zuvor, da auch der limitiert ist (meist aber größer als auto/Stack)

    Huch?
    Durch was ist static limitiert?

    UND du ebenfalls keine Abbruchprüfung in dein Programm einbauen kannst;

    Das eigentliche Problem ist dass die Sache mit static nimmer threadsafe ist. In diesem Fall natürlich wurst, da main() üblicherweise nur 1x läuft, aber man sollte mit dem Scheiss gleich gar nicht anfangen.



  • Wutz schrieb:

    for(a=0;a<30;a++)
    	for(b=0;b<30;b++)
    	for(c=0;c<30;c++)
    	for(d=0;d<13;d++)
    	p[a][b][c][d]=a*b*c*d;
    

    Und ich dachte ich hätte schon das Schlimmmste an Unübersichtlichkeit gesehen...



  • kalli schrieb:

    Und den Stack auf den das Array gehört kann ich mit malloc vergrößern, oder wie?

    Nein!

    Ein Programm besteht aus verschiedenen Teilen:
    Dem Programmcode, der ausgeführt wird,
    dem Datenbereich, in dem die konstanten Daten liegen, z.B. Strings wie das "bla.dat"
    und dem Stack, auf dem die Variablen angelegt werden und auch die Funktionsparamter übergeben werden.

    Code- und Datengröße ergeben sich aus dem Programm
    Die Stackgröße wird beim erzeugen des Programms festgelegt. Dies ist eine Konstante, d.h. sie wird nicht berechnet. (Man kann sie als Paramter für den Linker angeben)

    Dann ist aber immer noch ein Teil des Arbeitsspeichers frei. Dieser Bereich wird Heap genannt.
    Von diesen Heap kannst du Speicherplatz mit malloc anfordern.
    Die mögliche Größe hängt vom Speicherausbau des Rechners (auf dem das Programm läuft) und von dem gewählten Speichermodell (z.B. 32/64-Bit) des Programms/Betriebssystems ab.

    Das hat mit C eigentlich nichts zu tun.
    Das betrifft die Umsetzung auf reale Maschinen.



  • h würde sagen, dein Array ist zu groß für den Stack. Das nimmt ca. 1,4MB in Anspruch

    Kurze Frage, etwas OT: Wie berechnet sich das auf die schnelle?



  • how_much schrieb:

    h würde sagen, dein Array ist zu groß für den Stack. Das nimmt ca. 1,4MB in Anspruch

    Kurze Frage, etwas OT: Wie berechnet sich das auf die schnelle?

    30 * 30 * 30 * 13 * sizeof(unsigned int)?



  • EOP schrieb:

    Wutz schrieb:

    for(a=0;a<30;a++)
    	for(b=0;b<30;b++)
    	for(c=0;c<30;c++)
    	for(d=0;d<13;d++)
    	p[a][b][c][d]=a*b*c*d;
    

    Und ich dachte ich hätte schon das Schlimmmste an Unübersichtlichkeit gesehen...

    Kubkerlitzchen. Das war ja nur Null-Information.
    Krass wird esm wenn Einrückungen lügen!

    for(a=0;a<30;a++)
    		for(b=0;b<30;b++)
    			for(c=0;c<30;c++)
    for(d=0;d<13;d++)
    	p[a][b][c][d]=a*b*c*d;
    

Log in to reply