Problem mit dynamischer Allokation



  • 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 aufgetreten

    Jetzt 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


  • Mod

    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?


  • Mod

    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.



  • Vor allen Dingen solltest du für das Kopieren des Speicherbereiches die dafür vorgesehene Standardfunktion memcpy verwenden und keine Eigenbasteleien.

    Es sind leider nur die Bibliotheken stdio.h und stdlib.h erlaubt. Meine copyMemory Funktion ist eine Implementation von memcpy. Macht also genau das was auch memcpy macht.

    Probier jetzt schon einige Zeit herum die Nullterminierung zu inkludieren, komme jedoch auf keinen grünen Zweig.



  • Habs jetzt geschafft. Musste nur eine Zeile in mein copyMemory Funktion hinzufügen!

    Danke trotzdem für den Hinweis auf meine copyMemory Funktion!


Anmelden zum Antworten