malloc, realloc und free - wie kill ich das Array?



  • Hallo,

    Ich hab Probleme mit einem großen Speicherleck.
    Hier der Code:

    char ** readLinesFromFile (const char * const filename, int * lenght, int lineLenght) {
    	int count = 0; 
    	char **line = NULL; 
    	char * str = (char *) malloc(lineLenght * sizeof(char)); 
    	FILE * fp; 
    	if ((fp = fopen (filename, "r")) == NULL) 
    	{
    		showErrorMessage("Datei ",(char *)filename," konnte nicht gefunden. Programm wird beendet!\n","","");
    	}
    	while (fgets(str, lineLenght, fp)) 
    	{
    		count++; 
    		if (!line) 
    			line = (char **)malloc(count * sizeof(char *)); 
    		else 
    			line = (char **)realloc(line, count * sizeof(char *)); 
    		line[count - 1] = (char *)malloc(strlen(str) * sizeof(char)); 
    		strcpy(line[count - 1], str); 
    	}
    	line = (char **)realloc(line, (count + 1) * sizeof(char *)); 
    	line[count] = NULL; 
    	fclose(fp);
    
    	*lenght = count;
    	free(str);
    
    	return (line);
    }
    

    mit folgendem Aufruf

    char **Array = NULL; 
    
    	...
    
    	Array = readLinesFromFile (S_FILE_FOR_ZUFALLSGENERATOR, &iArrayLenght, I_DIC_STR_LEN);
    

    Wenn ich readLinesFromFile mehrmals aufrufe wird der Speicher immer voller...

    Also hab ich folgendes versucht

    ....
    free(Array);
    

    Dies brachte nicht den gewünschten Effekt, der Speicher wird imemr noch zugemüllt.

    und dies:

    int count = 0;
    	...
    
    	while (Array[i] != NULL) 
    	{
    		count ++;
    	}
    	{
    		int i = 0;
    		for (i; i < count; i++) 
    		{
    			free(Array[i]);
    			printf("#%i#",i);
    		}
    	}
    

    Das hier führt aber bei Programmausführung nur zur folgender Fehlermeldung :
    "DAMAGE: after Normal block(#45) at..."
    Eine Bildschirmausgabe ist nicht zu sehen...

    Wie kann "Array" aus dem Speicher entfernen und so das Speicherleck stopfen?



  • Du mußt zuerst alle Elemente des Arrays freigeben und zum Schluß das Array selbst.

    free (Array[0]);
    free (Array[1]);
    ...
    free (Array[n]):
    free (Array);



  • Bug schrieb:

    Du mußt zuerst alle Elemente des Arrays freigeben und zum Schluß das Array selbst.

    free (Array[0]);
    free (Array[1]);
    ...
    free (Array[n]):
    free (Array);

    Das Programm stürzt aber schon bei "free (Array[0]);" ab ( in der For-Schlefe)...



  • habe das programm etwas getestet.
    Du reservierst zu wenig specher für den neuen string. Diese Version funktioniert einwandfrei.

    #include <stdio.h>
    
    void showErrorMessage( const char * msg1,char * msg2,const char * msg3,const char * msg4,const char * msg5  ) {
       printf( "%s%s%s%s%s\n", msg1, msg2, msg3, msg4, msg5 );
    }
    
    char ** readLinesFromFile (const char * const filename, int * lenght, int lineLenght) {
        int count = 0;
        char **line = NULL;
        char * str = (char *) malloc(lineLenght * sizeof(char));
        FILE * fp;
        if ((fp = fopen (filename, "r")) == NULL)
        {
            showErrorMessage("Datei ",(char *)filename," konnte nicht gefunden. Programm wird beendet!\n","","");
        }
        while (fgets(str, lineLenght, fp))
        {
            count++;
            if (!line)
                line = (char **)malloc(count * sizeof(char *));
            else
                line = (char **)realloc(line, count * sizeof(char *));
            line[count - 1] = (char *)malloc((strlen(str)+1 ) * sizeof(char)); /* hier war dein fehler */
            strcpy(line[count - 1], str);
        }
        line = (char **)realloc(line, (count + 1) * sizeof(char *));
        line[count] = NULL;
        fclose(fp);
    
        *lenght = count;
        free(str);
    
        return (line);
    }
    
    int main() {
      char ** lines;
      int nlines;
      const char * fname = "fr.c";
      int i = 0;
      lines = readLinesFromFile(fname, &nlines, 100);
      printf("%d lines read\n", nlines ); 
      for ( i = 0; i < nlines; i++ )
        printf("%s", lines[i]);
    
      for ( i = 0; i < nlines; i++ )
        free(lines[i]);
      free ( lines );
    
      return 0;
    }
    

    Kurt



  • Vielen Dank 🙂 👍


Anmelden zum Antworten