Neuzuweisungsprobleme beim Zuweisen von Zeichenfolge zu dynamischem int-Array

Im Grunde versuche ich, eine Menge von char-Eingaben in ints zu konvertieren und sie einem dynamischen int-Array zuzuweisen. Die Zeichenfolgeneingabe und Tokenisierung scheinen gut zu funktionieren. Das Problem (von dem, was ich sagen kann) scheint mit der Neuzuweisung des int-Arrays zu sein; Nachdem das Array zweimal neu zugewiesen wurde, gibt der Zeiger auf das int-Array NULL zurück.

Was ich versuchte zu tun, war die Größe des int-Arrays jedes Mal zu verdoppeln, wenn die Anzahl der Token erreicht oder übertroffen wird (Größe geteilt durch sizeof (int)). Die realloc-Anweisung funktioniert jedes Mal, wenn diese Bedingung erfüllt ist.

Ich dachte, ein Zeiger auf einen Zeiger zu verwenden, war die Endlösung dafür. Ich wette, es ist ein wirklich offensichtliches Problem, aber ich bin hier mit meinem Verstand am Ende. Wenn Sie eine weitere Ausarbeitung wünschen, werde ich mein Bestes geben. Verstehen Sie, dass ich C nur für ein Semester genommen habe und den größten Teil des Wegs gekämpft habe.

Außerdem war dies Teil einer Klassenaufgabe, die seither bestanden hat. Ich würde eine Erklärung über das, was falsch ist, mehr als einen vollwertigen Code bevorzugen, wenn das in Ordnung ist.

Ich habe viele printf-Anweisungen, also Entschuldigung für jedes Durcheinander.

EDIT: Ersetzte alle Instanzen von newArray innerhalb der Funktion input() mit * resize. Ich habe jedoch nie versucht, Werte durch Zeiger auf Zeiger zuzuweisen, also fühlen Sie sich frei, mich mit einem syntaktischen Beispiel zu korrigieren, wenn Sie wissen, wie ich es vermasselt habe. Segmentierungsfehler tritt hier auf:

for (k = (numElem - count); k < numElem; k++)
{
    printf("\nk = %i\n", k);
    printf("j = %i\n", j);
    printf("numElem = %i\n", numElem);
    printf("results[j]: %s\n\n\n", results[j]);

    /* Segmentation fault regardless of what is assigned
    to *resize[k]. */
    *resize[k] = atoi(results[j]);//PROBLEM HERE
    j++;
}

Der Quellcode wurde aktualisiert, um dies zu berücksichtigen. Um diesen lächerlich langen Beitrag etwas gedämpfter zu machen, wollen wir sagen, dass ich das in main() getan habe:

    int *newArray = malloc(MAXTOKEN * sizeof(int));

    input(&newArray);  

    free(newArray);  

Weitergehen.

/* String input takes in char values,
tokenizes them, converts the results
to int, assigns them to newresizeay. */
int input(int **resize)
{
    int i, j, k, count;

    int numElem = 0;
    int currentSize = MAXTOKEN;

    char str[MAXSTRING];
    char *results[MAXTOKEN];

    /* This entire loop takes place at least once,
    provided the first input isn't NULL. */
    do
    {     
        i = 0, j = 0, k = 0;

        /* Char input process. Takes place until the user
        presses ENTER. */
        printf("Input integer values separated by spaces, or "
            "press ENTER to exit.\n");   
        while ( ((str[i] = getchar() ) != '\n') && (i < MAXSTRING) )
            i++;
        printf("\n\n");

        str[i] = '\0';


        /* Tokenization of the chars that were input */
        count = 0;

        if (results[0] = strtok(str, " \t"))
            count++;

        while (results[count] = strtok(NULL, " \t") )
            count++;


        /* numElem = 1 if the first input prompt established
        str[0] as NULL */
        if ( (count < 1) && (numElem < 1) )    
            count = 1;

        numElem += count;

        printf("numElem: %i\ncurrentSize: %i\n", numElem, currentSize);

        /* If the number of elements to assign meet or surpass
        the amount of [memory/sizeof(int)], exponentially
        increase the size of the int resizeay. */
        if ( numElem >= currentSize )
        { 
            *resize = realloc(*resize, (currentSize) * sizeof(int));
            if (*resize == NULL)
                printf("\n\nYep, it threw up.\n\n");
            currentSize *= 2;
        }


        printf("\nSize should be: %i\n", currentSize * 4);
        printf("Actual size: %d\n", _msize(*resize));


        /* The tokenized chars are converted to integers and
        assigned to the int resizeay. */
        for (k = (numElem - count); k < numElem; k++)
        {
            printf("\nk = %i\n", k);
            printf("j = %i\n", j);
            printf("numElem = %i\n", numElem);
            printf("results[j]: %s\n\n\n", results[j]);

            *resize[k] = atoi(results[j]);//PROBLEM HERE
            j++;
        }

        for (i = 0; i < numElem; i++)
            printf("resize[%i]: %i\n", i, *resize[i]);               

        printf("\n\n\n");      

    } while (str[0] != NULL);   

}
0
Ich habe das nicht tief durchgesehen, aber es sieht aus wie ein Problem mit Haufenproblemen.
hinzugefügt der Autor Jabberwocky, Quelle

3 Antworten

Unter underen Problemen:

char *results[MAXTOKEN];

sollte sein

char *results[MAXTOKEN + 1];

weil hier der maximale Wert von count in dieser Schleife MAXTOKEN ist:

while (results[count] = strtok(NULL, " \t") )
  count++;

und

char str[MAXSTRING];

ist ziemlich beängstigend, denn sobald der Benutzer mehr als MAXSTRIN (= 11) Zeichen eingibt, ohne Enter zu drücken, erhalten Sie einen Pufferüberlauf.

0
hinzugefügt

Die Eingabefunktion empfängt sowohl resize als auch arr . main sendet den gleichen Zeiger auf beide. Dies ist ein Fehler.

Wenn resize geändert wird, bleibt arr gleich und zeigt möglicherweise auf eine ungültige Adresse (wenn realloc eine andere Adresse zurückgibt).

Wie repariert man: Entfernen Sie das arr Funktionsargument und verwenden Sie nur resize .

0
hinzugefügt
Also müsste ich die atoi Werte als * resize [i] = atoi (Ergebnisse [j]) zuweisen? Als ich das tat, erschien der erste Wert des neuen int-Arrays gut, aber aufeinanderfolgende Einträge stürzten ab, sobald die Zuweisung für den fortlaufenden Index versucht wurde. Ich werde meinen Beitrag in Kürze bearbeiten.
hinzugefügt der Autor user3109954, Quelle
Ich sollte professioneller formulieren: Ich habe genau das gemacht, was Sie vorgeschlagen haben, und alles funktioniert perfekt. Zu sagen, dass ich dankbar bin, ist eine Untertreibung. Ich war davon besessen, und jetzt kann ich mich ausruhen.
hinzugefügt der Autor user3109954, Quelle
Verwenden Sie (* Größe ändern) [i].
hinzugefügt der Autor egur, Quelle
Sie können auch int * arr = * resize; deklarieren und damit arbeiten. Aktualisieren Sie die Größe nur vor dem Zurückgeben. realloc funktioniert mit arr .
hinzugefügt der Autor egur, Quelle

Wenn Sie die realloc-Funktion aufrufen, wird der ursprüngliche Speicher, wenn der neue Speicherblock kleiner als der vorherige ist, den ursprünglichen Zustand beibehalten, der auf den zuvor verwendeten Speicherblock zeigt. Wenn der neue Speicherblock größer als der vorherige ist, weist das System Speicher erneut zu Heap und der vorherige Speicher wird freigegeben.

0
hinzugefügt