Sowas hatte ich noch nie:



  • Hallo,

    Beim lesen einer Datei bekomme ich diese Fehlermeldung:

    malloc.c:2369: sysmalloc: Assertion `(old_top == (((mbinptr) (((char 😉 &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
    Aborted (core dumped)

    Routine sieht so aus:

    GMXGRO
    read_gro (FILE *file)
    {
    
     int i = 1, l = 0, a = 100, pos = 0L, lines = 0, length = 0;
     char groline[256];
     GMXGRO gro;
    
     /*** count lines ***/
     while (pos != EOF) {
      pos = fgetc(file);
      if (pos == '\n')
       lines++;
     }
     fseek(file, 0L, SEEK_SET);
    
     /*** read gro file ***/
     construct_GMXGRO(&gro, a);
     while(fgets(groline, sizeof(groline), file) != NULL) {
      length = strlen(groline)-1;
      if(groline[length] == '\n') 
       groline[length] = 0;
      if (a < (l+100)) {
       a *= 10;
       reconstruct_GMXGRO(&gro, a);
      }
      if (i == 1)
       gro.title = split_string(groline, 0, length);
      if (i == 2)
       gro.atoms = atoi(split_string(groline, 0, length));
      if(i > 2 && i < lines) {
       gro.A[l].resnr   = atoi(split_string(groline, 0, 4));
       gro.A[l].resname = split_string(groline, 5, 9);
       gro.A[l].atmname = split_string(groline, 10, 14);
       gro.A[l].atmnr   = atoi(split_string(groline, 15, 19));
       gro.A[l].c.x     = atof(split_string(groline, 20, 27)); ////<<-- hier zickt es...
       gro.A[l].c.y     = atof(split_string(groline, 28, 35));
       gro.A[l].c.z     = atof(split_string(groline, 36, 43));
       l += 1;
      }
      if(i == lines) {
       gro.box.x = atof(split_string(groline, 0, 9));
       gro.box.y = atof(split_string(groline, 10, 19));
       gro.box.z = atof(split_string(groline, 20, 29));
      }
      i += 1;
      gro.L = l;
      printf("lines = %d --- i = %d\n", lines, i);
     }
    
     /*** reallocation for optimal memory usage ***/
     reconstruct_GMXGRO(&gro, l);
    
     return gro;
    
    }
    

    und die split_string Funktion

    const char *
    split_string (char strin[], int pos1, int pos2)
    {
    
     int i = 0, slen = pos2 - pos1 + 1;
     char *str = malloc(slen*sizeof(char));
    
     for (i=0; i<slen; i++)
      str[i] = strin[pos1+i];
     str[slen] = '\0';
    
     return str;
    
    }
    

    Ich habe echt kein Rat, woher das kommt.

    Komischerweise funktioniert die Routine, wenn die eingelesene Datei nicht
    zu lang ist. Ein Beispiel: Wenn die Datei 2433 Zeilen hat, dann wird sie
    ordentlich eingelesen. Wenn sie aber z.B. 3122 Zeilen hat, dann zickt die
    Routine schon nach der 244. eingelesenen Zeile.

    Ich weiss nicht warum.

    Viele Gruesse,
    simsa



  • Wo sind die free für die ganzen malloc aus split_string ?



  • Hallo DirkB,

    wenn ich free(str) aus split_string mache, dann ist ja str leer und ich
    bekomme nichts... oder ich habe deine frage nicht verstanden. koenntest
    du es zeigen, was du meinst?

    gruesse,
    simsa



  • Wenn du kein free für die malloc machst, produzierst du Speicherlecks ohne Ende.
    Jedes malloc produziert ein Verwaltungsoverhead, der durchaus ein paar Zig Byte groß sein kann. (z.B.: 8 Byte Speicher, 16 Byte Verwaltung)

    Wenn du das free in split_string nicht machen kannst, dann musst du es eben nach dem Aufruf machen.
    Das sieht dann aber nicht mehr so elegant aus.
    Aber du musst es machen. Irgendwann in deinem Programm. Nur wenn du die Rückgabe von split_string verwirfst, kommst du da nicht mehr dran.

    Aber brauchst du an der Stelle überhaupt split_string ?
    Wie sind denn die Zahlen getrennt?
    Geht auch ein

    gro.A[l].c.x     = atof(groline+20);
    

    Wobei du mit strtod Fehler besser erkennen kannst.

    Hast du dir mal die Dateien angesehn, die den Fehler produzieren?
    Ist da eine Leerzeile oder überlange Zeile drin?
    In welchem Modus öffnest du die Datei?



  • Hallo DirkB,

    danke fuer deine Antwort/Hilfe.

    DirkB schrieb:

    Wenn du das free in split_string nicht machen kannst, dann musst du es eben nach dem Aufruf machen.

    naja, wie wuerde dass free() nach dem Aufruf der split_string funktion aussehen?

    ich kann ja nicht einfach free(split_string) schreiben.

    Die Zeilen, die ich einlesen haben 43 characters. Die sind leider nicht
    mit Tab oder Leerzeichen immer getrennt. Das Format, sieht so aus:

    "%5d%-5s%5s%5d%8.3f%8.3f%8.3f"

    gruesse,
    simsa



  • Du kannst
    - eine temporären char* verwenden

    char *c;
    c=split_string(...);x=atof(c);free(c);
    

    - noch split_i und split_f definieren, die den Wert zurückgeben und das free machen
    - split_string einen Buffer mitgeben.
    - split_string einen Buffer mitgeben. Wenn der Zeiger NULL ist, wird malloc genommen.

    Hast du schon mal ein sscanf-Formatstring versucht der deinen Text einlesen kann?
    ⚠ printf und scanf interpretieren die Formatspecifier unterschiedlich. Doku lesen.

    [🤡]
    Warst du schon zum Frustabbau mit einem Beil beim Schöpfer dieses Formates?
    Nicht für den Kopf, nur für die Finger, damit er so einen Mist nicht noch einmal macht.
    [/🤡]



  • danke, DirkB.

    ich werde es ausprobieren.

    gruesse,
    simsa


Anmelden zum Antworten