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 ganzenmalloc
aussplit_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 diemalloc
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
insplit_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 vonsplit_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 eingro.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
insplit_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* verwendenchar *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