Problem mit dynamischer Allokation
-
Hi,
hab ein Problem bezüglich dynamischer Allokation. Und zwar muss ich den eingelesenen String nach bestimmten Trennzeichen trennen und die getrennten Wörter in Arrays abspeichern. Mein Problem bei meinem Programm, ich muss dem zweidimensionalen Array einen Größe vorgeben, damit es funktioniert. Eigentlich sollte es sich je nach Größe des eingelesenen Strings dynamisch an die Größe anpassen.
Bei meinem Programm kann ich leider nur schriftlich wiedergeben, was ich programmiert habe, da die Plagiatkontrollen so streng sind! Ich werde aber versuchen es so gut wie möglich hinzubekommen.
char *single_words[256]; char *input_string; char number_of_saved_words; input_string = readInput(); number_of_saved_words = splitInputIntoSingleWords(input_string, single_words); int splitInputIntoSingleWords(char *input_string, char **single_words) { int number_of_words = 0; int counter = 1; while(*input_string) { if(Trennzeichenabfrage) { if(counter größer 1) { für single_words(Array) an der Stelle number_of_words soll jetzt genau eine Speicher der Größe alloziert werden (mit malloc), die der Anzahl des Counters entspicht + 1 für das NULLBYTE. memcopy(single_words(Array) an der Stelle number_of_words, input_strin - (counter -1), (counter - 1)); number_of_words inkrementieren } counter NULL setzen; } *input_string inkrementieren counter inkrementieren } return number_of_words; }
Wie kann ich das Array jetzt dynamisch auf die Anzahl der Wörter zwischen den Trennzeichen allozieren?
Eingelesener Text: Hallo, Welt!
array[0] = Hallo
array[1] = Welt!Wie in diesem Fall genau auf 2.
Bei mir ist das Array aber schon vordefiniert mit 256, d.h., es würde dann also so aussehen:
array[0] = Hallo
array[1] = Welt!
array[2] = (leer)
array[3] = (leer)
.
.
.
array[255] = (leer)Wie kann ich das Array jetzt ohne die Arraygröße vorher zu definieren, dynamisch gestalten, also ohne diese [256], es soll ja dynamisch sein
char *single_words[256];
Jetzt probier ich schon seit einiger Zeit herum, komm aber einfach nicht auf das Ergebnis.
Ich hoffe hier kann mir jemand helfen, wie ich das Problem lösen kann.
Der fehlende Programmcode kann meines Erachtens nicht viel länger als 5 Zeilen sein, es kann aber auch sein, dass ich vollkommen falsch liege.mfg Gabriel
-
char **single_words; single_words = malloc(256 * sizeof(*single_words));
Wenn der Platz nicht reicht, dann nimm realloc().
Statt (leer) solltest du NULL nehmen.
-
Nyquist schrieb:
Wie kann ich das Array jetzt ohne die Arraygröße vorher zu definieren, dynamisch gestalten, also ohne diese [256], es soll ja dynamisch sein
char *single_words[256];
Dazu müsstest Du VOR dem Allokieren wissen, wieviel Wörter das Array aufnehmen soll:
char **single_words = malloc(number_of_words * sizeof(char *));
Wenn Du das aber mit jedem gefundenen Wort 'mitwachsen' lassen willst, musst Du immer wenn ein weiteres Wort hinzukommt, neuen Speicher für einen Zeiger mehr allokieren (realloc).
-
char **single_words; single_words = malloc(256 * sizeof(*single_words));
Aber wenn ich das jetzt so mache, dann schaffe ich ja ebenfalls Platz für 256. Ich muss aber genau so viel Platz schaffen, wie Wörter drinstehen, also um auf mein Beispiel zurückzukommen
Eingelesener Text: Hallo, Welt!
array[0] = Hallo
array[1] = Welt!somit müsste jetzt mein single_words genau
single_words = malloc(2 * sizeof(*single_words));
sein.
Oder verstehe ich da irgendwie etwas falsch? Es muss dynamisch sein.
mfg
-
http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/
Allerdings lohn es sich nicht für jedes Wort ein realloc zu machen.
Du solltest großzügiger sein und dir immer Platz für 20 oder 50 oder 100 Wörter holen.Oder du nimmst eine verkettete Liste.
-
char **single_words = 0;
void *tmp;
int number_of_words = 0;...
wenn neues Wort gefunden:
++number_of_words;
tmp = realloc(single_words, number_of_words * sizeof(char *));
if(tmp)
single_words = tmp;
else
Fehler beim Allokieren aufgetretenJetzt kann an single_words[number_of_words - 1] der für das neue Wort erforderliche Speicher zugewiesen werden.
-
Deinen Ansatz hab ich jetzt verstanden, nur kann ich es leider nicht umsetzen
in der if Anweisung bei (counter > 1) steht nun folgendes
++number_of_words; temp = realloc(single_words, number_of_words * sizeof(char *)); if(temp) single_words = temp; single_words[number_of_words - 1] = (char *)malloc((counter * sizeof(char)) + CONSTANT_ONE); copyMemory(single_words[number_of_words-1], input_string - (counter - CONSTANT_ONE), (counter - CONSTANT_ONE));
in der main:
char **single_words;
So funktioniert es irgendwie nicht. Hab echt keine Ahnung mehr wie ich es machen soll, bin nämlich nicht so geübt in c.
mfg
-
WAS funktioniert nicht?
Hast du single_words vor der ersten Benutzung auch initialisiert?
char **single_words = NULL;
-
Das wird daran liegen, dass in
int splitInputIntoSingleWords(char *input_string, char **single_words)ja jetzt single_words geändert wird. So wie im Moment, wirkt sich diese Änderung nur innerhalb dieser Funktion aus. Du musst stattdessen einen Zeiger auf single_word übergeben:
int splitInputIntoSingleWords(char *input_string, char ***single_words)und beim Aufruf:
splitInputIntoSingleWords(..., &single_words);
-
Ja ich hab das
char **single_words = NULL;
initialisiert, jedoch macht das Programm jetzt garnichts mehr.
Auch nicht, wenn ich
int splitInputIntoSingleWords(char *input_string, char ***single_words) splitInputIntoSingleWords(..., &single_words);
im Code verwende.
Hab keine Ahnung, wie es weiter gehen soll
-
Da Du nun einen Zeiger auf single_words in der Funktion hast, musst Du an den Stellen, wo Du mit single_words arbeiten willst, nun diesen Zeiger dereferenzieren, zB statt:
memcopy(single_words(Array)
jetzt
memcopy((*single_words)(Array)
-
Ich hab Dir mal ein Minimalbeispiel(ohne Fehlerbehandlung und Speicherfreigabe) gemacht:
#include <stdio.h> #include <stdlib.h> void addWort(const char *wort, char ***single_word, int number_of_words) { void *tmp = realloc(*single_word, number_of_words * sizeof(char *)); *single_word = tmp; (*single_word)[number_of_words - 1] = malloc(strlen(wort) + 1); strcpy((*single_word)[number_of_words - 1], wort); } int main() { int i; int number_of_words = 0; char **single_words = 0; ++number_of_words; addWort("Wort eins", &single_words, number_of_words); ++number_of_words; addWort("Wort zwei", &single_words, number_of_words); ++number_of_words; addWort("Wort drei", &single_words, number_of_words); ++number_of_words; addWort("Wort vier", &single_words, number_of_words); for(i = 0; i < number_of_words; ++i) printf("%s\n", single_words[i]); }
-
Also wenn schon, dann die Anzahl auch gleich mit aktualisieren lassen.
#include <stdio.h> #include <stdlib.h> void addWort(const char *wort, char ***single_word, int *number_of_words) { *single_word = realloc(*single_word, ++*number_of_words * sizeof*single_word); strcpy((*single_word)[number_of_words - 1] = malloc(strlen(wort) + 1, wort); } int main() { int i; int number_of_words = 0; char **single_words = 0; addWort("Wort eins", &single_words, &number_of_words); addWort("Wort zwei", &single_words, &number_of_words); addWort("Wort drei", &single_words, &number_of_words); addWort("Wort vier", &single_words, &number_of_words); for(i = 0; i < number_of_words; ++i) printf("%s\n", single_words[i]); }
-
Hi,
danke für die sehr ausführlichen Erklärungen und ein großes Lob für die Sourcecodes!
Mein Programm funktioniert jetzt einwandfrei! Danke!mfg
-
Hi,
jetzt bin ich auf ein Problem gestoßen, aus dem ich nicht schlau werde. Bei meinem Programm fügt er beim 4-ten Wort, das ich eingebe immer irgendwelche Zeichen dazu. Bin mir vollkommen unschlüssig darüber, warum er das tut.
Die Funktion splitInputIntoSingleWords ist gleich aufgebaut wie am Anfang nur, dass sie nun folgendermaßen aussieht:
int splitInputIntoSingleWords(char *input_string, char ***single_words)
Aufgerufen wird die Funktion so:
splitInputIntoSingleWords(input_string, &single_words);
die if Anweisung wurde geändert auf:
if(counter größer 1) { (*single_words) = realloc(*single_words, ++array_size * sizeof(*single_words)); (*single_words)[array_size -1] = (char *)malloc((counter * sizeof(char)) + 1); copyMemory((*single_words)[array_size - 1], input_string - (counter - 1), (counter - 1)); }
Keine Ahnung, warum er mir immer beim 4-ten eingegebenen Wort immer irgendwelche Zeichen hinzufügt. Bin schon fast am Verzweifeln. Ich hoff es kann mir jemand helfen!
mfg
-
Klingt schwer nach vergessener Nullterminierung.
-
Klingt schwer nach vergessener Nullterminierung.
Ja aber wieso tritt dieser Fehler genau beim 4-ten auf? Hab jetzt Probiert einen längeren Text einzugeben und es treten mehrere dieser Fehler auf. An der 4-ten immer und dann zwischen 19-23.
Weiß einfach nicht was ich tun soll. Wenn es die Nullterminierung wäre, dann würde er doch bei jedem Wort einen Fehler einbauen nicht nur bei gewissen oder?
-
Undefiniertes Verhalten ist nun einmal schwer vorhersagbar.
Diese Zeile hier sieht jedenfalls schon einmal sehr danach aus, als würde die Nullterminierung nicht gemacht:
copyMemory((*single_words)[array_size - 1], input_string - (counter - 1), (counter - 1));
-
Jetzt muss ich sozusagen nach jedem kopierten Wort noch ein \0 miteinfügen.
Wie muss ich jetzt die Zeile umschreiben, damit dann eine Nullterminierung gemacht wird?
-
Vor allen Dingen solltest du für das Kopieren des Speicherbereiches die dafür vorgesehene Standardfunktion memcpy verwenden und keine Eigenbasteleien.