Speicherprobleme bei sehr großen struct arrays



  • FrEEzE2046 schrieb:

    Was für Speicherfehler bekommst du denn?

    ich dachte das geht nicht durch den compiler 😕

    lg lolo



  • Jürgen123 schrieb:

    leider bekomm ich da speicher fehler

    okay okay hab mein fehler schon gefunden 😞 muß mal die posts genauer lesen

    lg lolo



  • Danke schonmal!
    hab ich mir schon fast gedacht mit dem malloc, nur hapert es an der praktischen umsetzung:)
    haette ich jetzt z.b. jo batch; anstelle von jo batch[n][n]
    dann waere es ja wenn ich mich nicht irre einfach:

    batch = (struct jo *) malloc(sizeof(struct jo));
    free(batch);
    

    aber vielleicht kann mir jemand sagen wie das für das array aussieht..



  • Entfern die mehrfachen Dimensionen und reduzier alles auf eine Dimension, dann ist es viel einfacher.

    struct Foo *f = malloc(sizeof(*f) * 50); /* Platz für 50 mal struct Foo */
    


  • // alte Variante:
    struct jo batch[501][501];	// aufm Stack
    
    // neue Version:
    struct jo** batch = malloc(sizeof(struct jo*) /* 4 o. 8 */ * 501);		// reserviere Speicher für die ganzen Pointer
    for( i = 0; i < 501; i++ )
    	batch[i] = malloc(sizeof(struct jo) * 501);							// reserviere Speicher für 501 structs pro Pointer
    


  • Jürgen123 schrieb:

    Danke schonmal!
    hab ich mir schon fast gedacht mit dem malloc, nur hapert es an der praktischen umsetzung:)
    haette ich jetzt z.b. jo batch; anstelle von jo batch[n][n]
    dann waere es ja wenn ich mich nicht irre einfach:

    batch = (struct jo *) malloc(sizeof(struct jo));
    free(batch);
    

    aber vielleicht kann mir jemand sagen wie das für das array aussieht..

    1. Es wäre jo *batch (man beachte das Sternchen!), denn du willst einen Speicherbereich erzeugen, auf den du mit einem Zeiger zugreifen kannst.

    2. sizeof(struct jo) musst du mit der Anzahl der Elemente deines Wunsch-Arrays multiplizieren. Wenn du also ein 3*500*500-Array haben willst, dann musst du auch sizeof(struct jo)*3*500*500 Bytes allozieren.

    3. In C sollst du die Rückgabe von malloc nicht casten! Also lass den "(struct jo *)"-Cast weg.



  • also ich hab jetzt:
    [cpp]
    const int n=500, number_machines=3;
    struct jo{
    int process;
    int capacity;
    int release;
    };
    jo *batch[n][n] = malloc(n*n*sizeof(struct jo));

    allerdings kommt da einmal subscripted value is neither array nor pointer
    und "jo" undeclared first use in this function

    ?? 🙂



  • oh sorry, hatte die antwort von freeze total übersehn, das funktioniert so wunderbar:)
    Danke an alle!!!



  • Jürgen123 schrieb:

    oh sorry, hatte die antwort von freeze total übersehn, das funktioniert so wunderbar:)
    Danke an alle!!!

    Vergiss nicht am Ende für jeden Aufruf von malloc() auch einmal free() aufzurufen.



  • Hey Freeze, vielleicht kannst du mir nochmal helfen:)

    habe wohl das prinzip noch nich so hundertprozentig verstanden..

    2dimensionale variante

    batch[501][300]
    struct jo** batch = malloc(sizeof(struct jo*) *501 * 300);        // reserviere Speicher für die ganzen Pointer
    for( i = 0; i < 501; i++ ){
           batch[i] = malloc(sizeof(struct jo)*300);
    }
    

    so wenn ich jetzt aber 3 dimensional bin läuft das schon nichmehr:)

    clone[3][501][300]
    struct jo*** clone=malloc(sizeof(struct jo*)*3*501*300);
    for( i = 0; i < 3; i++ ){
         clone[i] = malloc(sizeof(struct jo)*501*300);
    }
    for( i = 0; i < 3; i++ ){
    for(j=0;j<501;j++){ clone[i][j] = malloc(sizeof(struct jo)*300);
    }}
    

    ich frag mich auch ob der speicher so richtig wieder freigegeben wird:

    free(batch);
    for(i=0;i<n;i++)
        free(batch[i]);
        }}
    

    Vielen Dank schon mal wieder im Voraus!



  • Jürgen123 schrieb:

    ich frag mich auch ob der speicher so richtig wieder freigegeben wird:

    free(batch);
    for(i=0;i<n;i++)
        free(batch[i]);
        }}
    

    Du gibst den Speicher für batch frei und greifst anschließend auf genau diesen Speicher zu. Kannst jetzt mal selbst überlegen ob das so richtig ist.



  • Jürgen123 schrieb:

    habe wohl das prinzip noch nich so hundertprozentig verstanden..

    2dimensionale variante
    ...

    Das ganze mit so vielen Zeigern zu machen ist teuer, weil es immer was kostet, einem Zeiger nachzulaufen. Ich würde gleich ein Array nehmen und es beim Zugriff in einen Array-Typ casten, würde mit einem Schlag die ganzen Zeiger entfernen.

    Beispiel mit int's:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        // genug Platz für eine 2x2-Matrix
        int *p = malloc(sizeof(int) * 2 * 2);
    
        p[0] = 0;
        p[1] = 1;
        p[2] = 2;
        p[3] = 3;
    
        for (int i = 0; i < 2; i++)
            for (int j = 0; j < 2; j++)
                printf("p[%d][%d] -> %d\n", i, j, ((int (*) [2])p)[i][j]);
    
        free(p);
        return 0;
    }
    

    🙂



  • das heisst mit free(batch); lösche ich alle elemente auf einmal, sehr gut:)



  • Jürgen123 schrieb:

    das heisst mit free(batch); lösche ich alle elemente auf einmal, sehr gut:)

    Nein.

    Mit free(batch) gibst du das dynamische Array selbst frei. Nicht die Elemente im Array.

    Aber du gibst das dynamische Array frei, greifst aber direkt danach auf dieses Array zu -> Böse. Ganz böse.



  • ohje das is auch alles sch*****
    da faellt mir nämlich auch auf dass ich das ganze ja so dann garnich im header allokieren kann. die strukturen sollen aber global in mehreren funktionen bekannt sein:(



  • Jürgen123 schrieb:

    ohje das is auch alles sch*****
    da faellt mir nämlich auch auf dass ich das ganze ja so dann garnich im header allokieren kann. die strukturen sollen aber global in mehreren funktionen bekannt sein:(

    Richtig: Programm vernünftig designen.

    Quick & Dirty: Globale Variable nutzen (Deklarationen mit Schlüsselwort extern, Definition in einer Source Datei) mit init-Funktion zum allokieren des Speichers.



  • Darf man fragen, was du überhaupt machen willst. Gibt es wirklich einen Sinn für deine 3 dimensionalen arrays oder machst du das nur so aus Spaß?

    Denn irgendwie ist schon beim Eröffnungspost ein ziemlich krasser Designmakel zu erkennen.



  • Janjan schrieb:

    Richtig: Programm vernünftig designen.

    Gute Idee. Aber ist es denn vernünftiges Design, 450900 unnötige Zeiger zu haben, die nur Probleme machen, und über 450900 mal malloc() und free() aufzurufen?

    Jürgen123 schrieb:

    ohje das is auch alles sch*****

    Warum nicht einfach ein grosses Array von Strukturen nehmen? Wenn dich die mehrdimensionalen Arrays verwirren, kannst du ja die 1d-Indizes auch selbst berechnen.
    🙂



  • mngbd schrieb:

    Janjan schrieb:

    Richtig: Programm vernünftig designen.

    Gute Idee. Aber ist es denn vernünftiges Design, 450900 unnötige Zeiger zu haben, die nur Probleme machen, und über 450900 mal malloc() und free() aufzurufen?

    Nein. Habe ich auch nie behauptet.



  • mngbd schrieb:

    Janjan schrieb:

    Richtig: Programm vernünftig designen.

    Gute Idee. Aber ist es denn vernünftiges Design, 450900 unnötige Zeiger zu haben, die nur Probleme machen, und über 450900 mal malloc() und free() aufzurufen?

    Stimmt gar nicht. Die innerste Dimension ist ja ein zusammenhängender Bereich von Strukturen und nicht von Zeigern. Die Zahl ist 1503.
    🙂


Anmelden zum Antworten