free führt zum crash...



  • Hallo.

    In meinem Code führt das Freigeben des allocierten Speichers zum Absturz.
    Ich habe ein einfaches Beispiel gebastelt, da tritt der Fehler allerdings
    nicht auf. Jedoch habe ich meinen Code so weit es geht ausgedünnt.

    unsigned long ReadMeshFile(char * filename, TElement **pElement, TBar **pBar, TNode **pNode, TFamily **pFamily, unsigned long * nElement, unsigned long * nBar, unsigned long * nNode, unsigned int * nFamily, unsigned long ** pExt2IntNodes){
    
    //Local variables
    unsigned int LineLength = 82;
    unsigned long nLines = 0;
    unsigned long fi = 0, fj = 0;
    char **Puffer=NULL;
    char line[82];
    struct stat FileStatus;
    
    //Checking if meshfile exists
    if (FileExist(filename)!=0){
    	printf("Unable to open file %s...\nPlease press any key...\n\n", filename);
    	system("PAUSE");
    	return 2;
    }
    
    //Getting Size of Meshfile
    stat(filename, &FileStatus);
    nLines = FileStatus.st_size/(LineLength*sizeof(char))+2;
    printf("	%lu lines to read...\n", nLines);
    
    //Allocating local memory for mesh file
    Puffer = (char **)calloc(nLines, sizeof(char *));
    fj=sizeof(char);
    do{
    	Puffer[fi] = (char *)calloc(LineLength, fj);
    }while(fi++<nLines); fi=0; fj=0;
    
    //Opening mesh file
    FILE *Mf = fopen(filename, "r");
    printf("	Meshfile opend for reading\n");
    
    //Reading meshfile and write to Puffer...
    
    //Closing mesh file
    fclose(Mf);
    printf("	Closing file meshfile...\n");
    
    //Clear memory
    printf("\tFree Puffer-memory...\n");
    free(Puffer); //Crash...
    return 0;
    }
    

    Das letzte was vor dem Absturz auf dem Bildschirm erscheint ist "Free Puffer-
    memory..." - dann hängt sich das Programm auf.

    Wenn ich den free() Befehl raus nehme, ist alles in Ordnung.

    Das Passiert nur, wenn ich den Code mit dem TCC Compiler compiliere, nicht
    beim LCC - der aber leider langsamer ist.

    Hat jemand einen Tip für mich?



  • Folgender Code führt beim TCC Compiler (auf dem gleichen Rechner) NICHT zum
    Absturz:

    //--------------------------------------
    //Included header files
    //--------------------------------------
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(){
    unsigned long nLines=100, fi=0;
    char ** Puffer=(char **)calloc(nLines, sizeof(char *));
    for (fi=0;fi<nLines;fi++){
    	Puffer[fi] = (char *)calloc(81, sizeof(char *));
    }
    
    //Do something
    
    free(Puffer);
    return 0;
    }
    


  • Wenn du uns hier Code zeigst wo der Fehler nicht auftritt, können wir die auch nicht helfen. 🙄

    Die Freigabe von den Puffer[i] fehlt noch. Das sollte aber nicht zum Absturz führen. (Ist aber trotzdem ein Fehler)

    Zeig mal die Zeile, in der du Daten nach line einliest.



  • Versuch es mal so

    //--------------------------------------
    //Included header files
    //--------------------------------------
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(){
    unsigned long nLines=100, fi=0;
    char ** Puffer=(char **)calloc(nLines, sizeof(char *));
    for (fi=0;fi<nLines;fi++){
    	Puffer[fi] = (char *)calloc(81, sizeof(char *));
    }
    
    //Do something
    
    for (fi=0;fi<nLines;fi++)
    	if(Puffer[fi]) free(Puffer[fi]);
    
    free(Puffer);
    return 0;
    }
    


  • Hallo.

    Hat leider nicht geholfen.
    Der code stürzt bei Puffer[0] schon ab.



  • Hallo Dirk.

    Hier der Code, wo ich "line" fülle und an Puffer übergebe:

    //Looping mesh file
    while(fgets(line, LineLength, Mf) != NULL){
    		if (strncmp(line, "GRID",4)==0) {
    			fnNode++;
    			EndLineNode = fi;
    			strcpy(Puffer[fi++], line);
    		} else if (strncmp(line, "CTRIA3",6)==0){
    			fnElement++;
    			fnTri++;
    			EndLineTri = fi;
    			strcpy(Puffer[fi++], line);
    		} else if (strncmp(line, "CQUAD",5)==0) {
    			fnElement++;
    			fnQuad++;
    			EndLineQuad = fi;
    			strcpy(Puffer[fi++], line);
    		} else if (strncmp(line, "CBAR",4)==0) {
    			fnBar++;
    			EndLineBar = fi;
    			strcpy(Puffer[fi++], line);
    		} else if (strncmp(line, "$       Bar element data for family    ", 39)==0) {
    			fnFamily++;
    			fpFamily = realloc(fpFamily, fnFamily * sizeof(TFamily));
    			for (fj=39; fj<=81;fj++) {if (line[fj]!=9 && line[fj]!=32 && line[fj]!='\n') {fpFamily[fnFamily-1].Name[fk++] = line[fj];}}
    			fpFamily[fnFamily-1].Name[fk]='\0';
    			fpFamily[fnFamily-1].number = fnFamily;
    			fk = 0;
    		} else if (strncmp(line, "$       Shell element data for family    ", 41)==0) {
    			fnFamily++;
    			fpFamily = realloc(fpFamily, fnFamily * sizeof(TFamily));
    			for (fj=41; fj<=81;fj++) {if (line[fj]!=9 && line[fj]!=32 && line[fj]!='\n') {fpFamily[fnFamily-1].Name[fj-41] = line[fj];}}
    			fpFamily[fnFamily-1].Name[fj-40]='\0';
    			fpFamily[fnFamily-1].number = fnFamily;
    			fk = 0;
    		}
    } nPuffer = fi; fi=0;
    


  • du darfst an free() nur adressen schicken die von malloc/calloc/realloc kamen. und das pro adresse auch nur ein mal.



  • In dem Beipiel sehe ich z.Zt. keinen Fehler der Puffer ändert.

    Alledings ein paar Anmerkungen:
    Zum testen ob ein Zeichen ein Whitespace ist, gibt es isspace aus ctype.h

    Den Speicher für die Zeilen solltest du erst besorgen, wenn du auch weißt wie lang diese sind. Sonst verschenkst du unnötig Speicher. Denke dabei auch an die '\0'

    LineLenght sollte const sein.

    Lass dir mal die Adresse ausgeben, die in Puffer steht

    Puffer=calloc(nLines, sizeof(char *));
    printf("Puffer-memory bei %p\n", Puffer);
    ...
    printf("\tFree Puffer-memory... %p\n", Puffer);
    free(Puffer);
    

    Die beiden Adressen sollten natürlich gleich sein.
    ... und Nutze den Debugger.


Anmelden zum Antworten