funktion zum dynamischen einlesen eines strings
-
hallo,
bin vorhin auf eine (meiner ansicht nach) sehr gut funktion zum dynamischen einlesen eines string gestoßen:
int readString( char** dest ) { int ch = 0, slen = 0; while( ( ch = fgetc( stdin ) ) != EOF ) { if( ch == '\n' ) { *dest = realloc( *dest, ( slen + 1 ) * sizeof( char ) ); if( *dest != NULL ) { (*dest)[slen++] = '\0'; return slen; } else { if( *dest ) free( *dest ); return -1; } } if( isalnum( ch ) ) { *dest = realloc( *dest, ( slen + 1 ) * sizeof( char ) ); if( *dest != NULL ) (*dest)[slen++] = ( char )ch; else { if( *dest ) free( *dest ); return -1; } } } return -1; }
aufgerufen wird diese funktion so:
fprintf( stdout, "Vorname ... : " ); if( ( dat->lenVName = readString( &( dat->vName ) ) ) == -1 ) { fprintf( stderr, "%s: Fehler beim Einlesen des Vornamens.\n", argv[0] ); freeNameData( dat ); return EXIT_FAILURE; }
dat ist hier eine struktur, die halt in dem fall z.b. die länge des vornamens speichert, und einen char *vName hat.
was haltet ihr davon, wie sinnvoll so eine funktion ist, bzw. ob man sie noch irgendwie optimieren kann? denn ich denke mal das ständige realloc ist schon ziemlich aufwändig bzw. unvorteilhaft ist oder?
-
Die Benutzung von realloc gefällt mir nicht, wenn realloc NULL zurückliefert, hat man einen Pointer verloren.
Ich würde die Speicherreservierung so machen: immer doppelt so viel, wie man hat und nur dann reservieren, wenn man keine freien Stellen hat (amortisierte Kosten sind minimal, wenn ich mich nicht irre).
Sprich: am Anfang habe ich 0 Zeichen, ich lese ein Zeichen also reserviere ich 3 (2 + 1 für \0). Das nächste Zeichen kann ich ohne Speichereservierung speichern (hab mir ein realloc Aufruf gesparrt). Beim dritten Zeichen muss ich wieder realloc aufrufen, dieses mal vergrößre ich den Speicher auf 5 Bytes. (aktuelle Länge * 2 + 1 für das \0). Dann sparre ich mir 2 realloc Aufrufe. Wenn ich das 5. Zeichen eingelesen habe, vergrößere ich den Speicher wieder, auf 11 Bytes (alte Länge * 2 + 1, sprich 5*2+1), usw.
-
am besten ohne malloc/realloc.
der funktion wird einfach ein pointer auf einen speicherbereich (und dessen grösse) gegeben, den sie benutzen darf.
wenn der speicher erschöpft ist, kommt sie mit einem status- bzw. fehlercode raus (out of memory o.ä.)
wenn man's dann mit dynamischem speicher braucht, schreibt man eben eine zweite funktion, die die erstgenannte aufruft, und den speicher bei bedarf erweitert...
-
vielen dank euch beiden! werde mal eure vorschläge umsetzen und dann noch mal ne laufzeitanalyse durchführen