C Unix free() -> invalid pointer()



  • Hallo,

    habe folgendes Problem mit meinem C-Code unter Unix (unter Windows funktioniert er problemlos). Ich Erzeuge mir ein zweidimensionales Array auf dem Heap, befülle es und gebe es wieder frei. Das Problem liegt bei dem free(). Das hier ist nur ein fiktives Beispiel. Habe den Code auch schon in verschiedene Arten umgeschrieben, aber immer das gleiche Problem.

    Code:

    int size = 5;
        char **matrix;
        matrix = malloc(size * sizeof(char *));
        int i = 0;
        while(i < size){
            matrix[i] = malloc(64 * sizeof(char));
            i++;
        }
    
        matrix[0] = "hello";
        matrix[1] = "hello";
        matrix[2] = "hello";
        matrix[3] = "hello";
        matrix[4] = "hello";
    
        int m = 0;
        while(m < size){
            free(matrix[m]);
            m++;
        }
        free(matrix);
    

    Fehlermeldung:
    *** glibc detected *** ./testfile: munmap chunk(): invalid pointer: 0x0000.....



  • Hierbei:

    matrix[0] = "hello";
        matrix[1] = "hello";
        matrix[2] = "hello";
        matrix[3] = "hello";
        matrix[4] = "hello";
    

    handelt es sich nicht um String-Kopien, sondern um Zeigerzuweisungen. Die Zeiger in matrix[0] bis matrix[4] zeigen danach auf ein String-Literal "hello", welches nicht auf dem Heap liegt und dementsprechend nicht mit free weggeräumt werden darf. Die ursprünglich vom Heap angeforderten Zeiger gehen verloren; somit hast du neben dem free-Problem noch Speicherlecks.

    Richtig wäre beispielsweise

    strncpy(matrix[0], "hello", 64);
        strncpy(matrix[1], "hello", 64);
        strncpy(matrix[2], "hello", 64);
        strncpy(matrix[3], "hello", 64);
        strncpy(matrix[4], "hello", 64);
    


  • Danke !



  • n0nam333 schrieb:

    Ich Erzeuge mir ein zweidimensionales Array auf dem Heap

    Nein, tust du nicht.
    Du reservierst 65 Speicherblöcke. Und befüllst sie mit Stringliteralen, also zur Compilezeit bekannten Strings.
    Das funktioniert natürlich für Strings, die erst zur Laufzeit bekannt sind, nicht.

    char a2[100][64]; /* das ist ein 2-dim. (char)Array */
    char (*a)[64]=calloc(100,64); /* definiert einen Zeiger, der auf einen dynamisch reservierten Speicherblock verweist und diesen als Folge von char-Blöcken mit jeweils 64 Elementen interpretiert */
    

Anmelden zum Antworten