Verfügbaren Speicher bestimmen



  • Der letzte Post stammt von mir, ich habe den falschen Namen gewählt.



  • iosdumpy schrieb:

    Das genaue Verhalten ist nicht definiert und selbst wenn 0 zurückgegeben würde, stürzt das Programm beim nächsten Zugriff darauf ab und wechselt nicht ins undefinierte Verhalten.

    Was genau ist "undefiniertes Verhalten" denn für dich?



  • iosdumpy schrieb:

    Ich habs getestet: er gibt den Wert 0x8f14008 zurück. Das genaue Verhalten ist nicht definiert und selbst wenn 0 zurückgegeben würde, stürzt das Programm beim nächsten Zugriff darauf ab und wechselt nicht ins undefinierte Verhalten.

    Ist definiert, und zwar entweder NULL oder ein Zeiger, den man nicht verwenden darf, aber free()'n muss.



  • Erstmal danke an euch,
    ich habe jetzt mal den Wert für MB erhöht, damit das ganze in halbwegs akzeptabler Zeit abläuft.

    #include <stdio.h>
    #include <stdlib.h>
    #define MB 1024000
    
    size_t alloc_test(char *c){
    
    	size_t mb=1;
    
    	while ((c=(char*) malloc(mb*MB))!=NULL){
    		free(c);
    		mb++;
    	}
    
    	while ((c=(char*) malloc((--mb)*MB)) == NULL);
    
    	return mb;
    }
    
    int main(void){
    
    	char* c;
    	long int size;
    
    	size = alloc_test(c);
    	printf("Zur Verfuegung stehender Speicher in Megabyte: %lu\n", size);
    
    	if (size>0) {
    	  	printf("Reservierter Speicher mit Addresse %p wird nun freigegeben...\n", c);
    
    		free(c);
    	}
    
    	return 0;
    }
    

    Da Problem besteht jetzt in Zeile 30. Durch das free entsteht folgender Fehler:

    Speicherzugriffsfehler (Speicherabzug geschrieben)
    

    Woran kann das liegen?

    Liebe Grüße!



  • In der ersten Schleife testest Du was der Speicher hergibt und
    gibst den immer wieder frei.

    Dann zählst Du die mb wieder mit alloc() herunter ohne den freizugeben.

    Zurück gibt alloc_test() die mb (eine int).

    Du übergibst einen Stringpointer an test_alloc(), der muß eigentlich
    NULL bzw Nirwana sein wenn die Funktion aufhört.



  • Ok, ich dachte, der wäre nicht NULL, denn es wird ja in

    while ((c=(char*) malloc((--mb)*MB)) == NULL);
    

    die Passage

    c=(char*) malloc((--mb)*MB)
    

    so häufig aufgerufen, wie c==NULL ist. Dann wird noch einmal aufgerufen und festegestellt, dass c!=NULL ist, aber um das festzustellen, muss ja erstmal auf Gleichheit geprüft werden, d.h.

    c=(char*) malloc((--mb)*MB)
    

    müsste noch einmal aufgerufen werden. Scheinbar habe ich da aber einen Denkfehler.

    Demnach sollte doch kein Speicherzugriffsfehler auftauchen, wenn ich

    while ((c=(char*) malloc((--mb)*MB)) == NULL);
    

    durch

    while ((c=(char*) malloc((--mb)*MB)) == NULL);
    c=(char*) malloc((mb)*MB);
    

    ersetze. In diesem Fall gibt es aber trotzdem einen Zugriffsfehler.
    Warum?

    Danke und liebe Grüße!



  • Um er einmal kurz und zusammen zu fassen 😉 :

    Warum führt folgender Code zu einem Speicherzugriffsfehler?

    #include <stdio.h> 
    #include <stdlib.h> 
    #define MB 10240000
    
    size_t alloc_test(char *c){ 
    
        size_t mb=1; 
    
        while ((c=(char*) malloc(mb*MB))!=NULL){ 
            free(c); 
            mb++; 
        } 
    
        while ((c=(char*) malloc((--mb)*MB)) == NULL); 
        c = (char*) malloc(mb*MB);
    
        return mb; 
    } 
    
    int main(void){ 
    
        char* c; 
        long int size; 
    
        size = alloc_test(c); 
        printf("Zur Verfuegung stehender Speicher in Megabyte: %lu\n", size); 
    
        if (size>0) { 
              printf("Reservierter Speicher mit Addresse %p wird nun freigegeben...\n", c); 
    
            free(c); 
        } 
    
        return 0; 
    }
    

    Liebe Grüße!



  • #define MB 10240000 //was das für ne größe? definierst du ein mb neu 😕

    denke das letzte free(c) bringt den wurm rein..



  • Der Fehler ist, dass mehrmals allokierter Speicher nicht notwendigerweise am gleichen Ort ist.

    size_t alloc_test(char *c){
      // *c zeigt auf stelle 0x234A
      c=malloc(...);
      // *c zeigt auf stelle 0x765B
    }
    

    Nachher hast du keine Möglichkeit mehr herauszufinden, wo der neue *c hinzeigt.
    Daher: pointer auf pointer übergeben.

    size_t alloc_test(char **c){
        size_t mb=1;
        while ((*c=(char*) malloc(mb*MB))!=NULL){
            free(*c);
            mb++;
        }
        while ((*c=(char*) malloc((--mb)*MB)) == NULL);
        *c = (char*) malloc(mb*MB);
        return mb;
    }
    
    // in main:
    size = alloc_test(&c);
    

    Das bringt sicher einen grossen Wurm rein.



  • Funktioniert, genau da lag der Denkfehler.
    Danke!


Anmelden zum Antworten