Anzeige:
Ergebnis 1 bis 6 von 6

Thema: realloc in Funktion auslagern

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177

    realloc in Funktion auslagern

    Hi!
    Ich habe mal wieder eine kleine Frage. Ich möchte gerne realloc in eine Funktion auslagern:
    Code:
    void reallData(Data **data, int rows){
    	
    	extern Count cnt;
    
    	data = (Data*) realloc(data, rows * sizeof(Data));
    	if(data == NULL){
    		fprintf(stderr, "out of memory\n");
    // 		return 0;
    	}
    	data[0].id = 75;
    	int i;
    	for(i = cnt.value_rows; i < cnt.value_rows+rows; i++){
    		data[i].value = (double*) malloc(cnt.value_colums * sizeof(double));
    		data[i].value = i;
    		if(data[i].value == NULL){
    			fprintf(stderr, "out of memory\n");
    // 			return 0;
    		}
    	}
    	
    }
    Doch erhalte nur Fehlermeldungen.
    Gelöst habe ich das Problem auch schon indem ich Data mit
    Code:
    extern Data data;
    in der Funktion initialisiert habe.
    Doch eigentlich interessiert mich, warum es nicht funktioniert? Meiner Auffassung nach müsste es dem Compiler doch egal sein, ob noch ein Zeiger auf die Struktur zeigt oder nicht. Die Aufklärung würde mich wirklich interessieren.

    Grüße dml!

  2. #2
    Registrierter Benutzer
    Registriert seit
    28.08.2002
    Beiträge
    496
    also, bei mir funktioniert das problemlos (aber nicht dein code)
    ein problem bei deinem code zeigt vielleicht folgendes minimalbeispiel:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void myrealloc(int **data,int rows){
            *data = realloc(*data,rows*sizeof(**data));
    }
    
    
    int main()
    {
            int *test;
            test = malloc(sizeof(int));
            myrealloc(&test, 5);
    
            for(int i = 0; i < 5; i++)
                    test[i] = 1;
    
            for(int i = 0; i < 5; i++)
                    printf("%d",test[i]);
    
            printf("\n");
    
            free(test);
            return 0;
    }
    Geändert von quinte17 (18-05-2013 um 10:30 Uhr)

  3. #3
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Zu dem eigentlichen Problem hat ja quinte17 schon was geschrieben.

    Hierzu habe ich aber noch eine zusätzliche Anmerkung:

    Zitat Zitat von dml Beitrag anzeigen
    data = (Data*) realloc(data, rows * sizeof(Data));
    if(data == NULL){
    fprintf(stderr, "out of memory\n");
    // return 0;
    }
    So bastelt man sich ein Speicherleck, denn wenn realloc() fehlschlägt, ist der ursprüngliche Speicher immer noch belegt. Also sollte man den Rückgabewert von realloc() in eine temp. Variable speichern, und erst dann "data" neu zuweisen, wenn es geklappt hat. Im Fehlerfalle kann man so noch den alten Speicher mit free( *data ) freigeben.

    int i;
    for(i = cnt.value_rows; i < cnt.value_rows+rows; i++)
    So knallt es natürlich, wenn man data[i] verwendet und cnt.value_rows != 0 ist.

    data[i].value = (double*) malloc(cnt.value_colums * sizeof(double));
    data[i].value = i;
    Ja, welcher Wert soll denn nun in data[i].value rein, da mußt du dich schon entscheiden

    if(data[i].value == NULL){
    fprintf(stderr, "out of memory\n");
    // return 0;
    }
    Hier vermisse ich in der Fehlerbehandlung wieder das Freigeben des bisher belegten Speichers.
    Geändert von sommerfee (16-05-2013 um 21:34 Uhr)

  4. #4
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177

    Übung macht den Maeister!

    Hi,
    vielen Dank für Eure Unterstützung. Das Speicherleck wäre mir für eine längere Zeit, wenn überhaupt, gar nicht erst, aufgefallen. Ich habe noch eine Variante ausprobiert:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void mymalloc(int *data,int rows){
            data = malloc(rows*sizeof(*data));
    }
    
    void myrealloc(int *data,int rows){
            data = realloc(data,rows*sizeof(*data));
    }
    
    void myrealloc2(int **data,int rows){
            *data = realloc(*data,rows*sizeof(**data));
    }
    
    
    int main()
    {
            int *a;
            printf("&a=%p, a=%p\n",&a,a);
            a = malloc(sizeof(int));
    //         mymalloc(a, 1);
            printf("&a=%p, a=%p\n",&a,a);
            myrealloc(a, 6);
            printf("&a=%p, a=%p\n",&a,a);
    	
            int *b;
            b = malloc(sizeof(int));
            myrealloc2(&b, 6);
    
    	int i;
            for(i = 0; i < 6; i++){
                    a[i] = 1;
                    b[i] = 1;
    	}
    
            for(i = 0; i < 6; i++){
                    printf("%d\n",b[i]);		
    	}
    
    	
            printf("\n");
    
            free(a);
            free(b);
    	
            return 0;
    }
    Was zeigen würde, das ein Doppelpointer gar nicht erst benötigt wird.
    Vielen Dank!
    Geändert von dml (17-05-2013 um 14:43 Uhr)

  5. #5
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Zitat Zitat von dml Beitrag anzeigen
    Was zeigen würde, das ein Doppelpointer gar nicht erst benötigt wird.
    Natürlich wird der Doppelpointer benötigt, zumindest in C, und wenn man es so macht wie du. mymalloc() und myrealloc() verändern lediglich die lokale Variable "data", deren Gültigkeitsbereich nur bis zum Funktionsende reicht.

    Dementsprechend solltest du hier
    printf("&a=%p, a=%p\n",&a,a);
    myrealloc(a, 6);
    printf("&a=%p, a=%p\n",&a,a);
    beide Male den gleichen Wert für "a=" ausgegeben bekommen.

    Und daß die Zuweisungen hinterher funktionieren, hat überhaupt nichts zu sagen, du pinselst halt über deinen zugewiesenen Speicherbereich hinüber, das kann später wildeste Auswirkungen haben. (C ist halt nicht Pascal oder Java. BTW: Nimm mir es nicht übel, aber kaufe dir ein Buch, welches solche elementaren Grundlagen besser als dein vorhandenes Lehrbuch vermittelt.)
    Geändert von sommerfee (18-05-2013 um 09:02 Uhr)

  6. #6
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177

    ein bisschen Angeberei

    Code:
    &(*data)[i]
    Hat echt ein paar Tage gedauert bis ich bemerkt habe, das ich das Feld und nicht den Zeiger ansprechen muss.

    Dank an Euch!
    Geändert von dml (24-05-2013 um 23:42 Uhr) Grund: Grammatik

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •