Frage

Mit dem folgenden Code, erhalte ich ein sehr sonderbares Ergebnis. Warum ist der Wert des letzten Elements überschreiben alle bisherigen Elemente Array? Ich vermute, es gibt ein größeres Problem als nur dieses ermöglichen rasches Problem.

#include <stdio.h>

main()
{
    int i, cases;
    char num[1000000];

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        scanf("%s", &num);
        array[i] = &num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value) 
        printf("%d %p\n", i, &array[i]); //print (array index) (array address) 
    }
}

Inputs:
3 <-- number of lines to follow
0   <-- put in array[0]
1   <-- put in array[1]
2   <-- put in array[2]

Outputs
0 3         <-- why is this being overwritten with the last element?
0 0013BCD0
1 3         <-- why is this being overwritten with the last element?
1 0013BCD4
2 3
2 0013BCD8

Keine korrekte Lösung

Andere Tipps

Das Ergebnis ist hier die Linie array[i] = &num; Sie den Wert des array[i] Element an die Adresse des num Array sind einstellen; da array ein char-Array ist, vermute ich, es Adresse Ihre num Array ist Kürzen und das niederwertige Byte geschieht nur 3.

sein

Allerdings. Das heißt, Ihre char num [1000000] ist abscheuliche Form, und Sie sollten das nicht tun, überhaupt nicht. Weisen Sie auf dem Heap, und wählen Sie eine kleinere Zahl, um Himmels willen. Auch die scanf ( „% s“, & num) wird nicht wirklich geben Sie, was Sie wollen. Hier ein Tipp; verwendet einen getc () -Schleife, die Zahlen zu lesen; Dies vermeidet Vorbelegung eines Arrays für scanf zu tun, um ().

Es ist, weil Sie in jedem Index des Arrays die gleiche Adresse (die Adresse des char num [1000000];) setzen.

Es ist ein Fehler, den Sie dynamische Zuordnung (calloc, malloc, neu, usw.).

führen

Cheers!

In Ihrer ersten Schleife, sollten Sie (aber Sie sind nicht) jede Eingabe in ein anderes Element des num-Array zu schreiben; stattdessen sind Sie immer an der gleichen Stelle zu schreiben, das heißt &num.

char * array [Fälle];

Das bei der Kompilierung-Zeit zugewiesen wird, nicht zur Laufzeit. Und Fälle nicht initialisiert ist (obwohl ich glaube, Sie wollen es trotzdem dynamisch arbeiten.) Daher muss man entweder den Speicher vorzuzubelegen, oder mit der malloc-Familie von Bibliotheksfunktionen vertraut machen.

Ersetzen

//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", &num);
    array[i] = &num;
}

mit

array[0] = num;
//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", array[i]);
    array[i+1] = array[i] + strlen(array[i]) + 1;
}

jede Zeichenfolge in den ersten verfügbaren Platz in num[] zu scannen, und legen Sie das nächste Element von array[] auf den nächsten verfügbaren Raum zu zeigen. Jetzt ist Ihr printf() der Saiten funktionieren. Das Original wurde das Scannen jeden Zeichenfolge in Beginn num[].

Hinweis:.. scanf() mit schmucklos %s ist so schlecht, wie gets(), weil es keine Begrenzung für die Datenmenge setzt, die in geschlürft werden Sie es nicht in echtem Code verwendet

Ersetzen

    printf("%d %p\n", i, &array[i]); //print (array index) (array address) 

mit

    printf("%d %p\n", i, (void*)(array[i])); //print (array index) (array address) 

drucken tatsächlich die in a[] gespeicherten Adressen, anstatt die Adressen der Elemente der a[]. Die Besetzung ist erforderlich, da %p einen Zeiger-tovoid erwartet, so dass Sie ein bereitstellen muss.

Das ist Ihr Code, der festgelegt ist:

#include <stdio.h>

main(void)
{
    int i, cases;

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        char *num = malloc(100000);
        scanf("%s", num);
        array[i] = num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value)
        printf("%d %p\n", i, (void*)&array[i]); //print (array index) (array address)
    }
    return 1;
}

Sie können auch verwenden

char *num = calloc(100000, sizeof(char));

, das ist ein wenig defensiv. Ich weiß nicht, warum Sie 100000. brauchen Sie können es tun dynamisch malloc. Dies wird mehr Arbeit bedeutet, ist aber sehr robust.

Was ist in Ihrem Code hapenning ist, dass Sie die Zeichenfolge% s speichern, um die Adresse von num, die sich nicht ändert, dann weisen Sie array [i] Element an diese Adresse. Zuweisen von in C ist nichts anderes als die Referenz zu speichern, speichern Sie nicht das Element itself- dies wäre Platzverschwendung sein. So wie alle der Array-Elemente an die Adresse zeigen (nur die Referenz speichern), um den Wert in der Adressänderung, so dass damit auch der Hinweis, das ist, warum sich alle 2 ändern (nicht mehr als 3, wie Sie in Ihrem Beitrag angegeben).

Es ist für solche Dinge, die C ++ gemacht zu werden scheint. Die Benutzereingabe-Analyse und dynamische Zuweisungen sicherer gemacht, und in einer Brise. Ich kann nicht von einem System denken, wo Sie diese Art von einer Benutzeroberfläche haben, wo man nicht zu C ++ wechseln könnte.

Natürlich, wenn dies nur ein Test Auszug aus anderem Code, der von dem Problem leidet, dann natürlich ...


Ihr Code hat mehrere häufigen Fehler für C Anfänger und Dinge, die nicht auf diese Weise heute getan werden sollte.

Wenn ich richtig verstehe, Sie sereval Benutzereingabe Strings (Ihr Beispiel Ausgabe ist ein wenig irreführend, weil Sie nur Zahlen zeigen) gespeichert werden soll.

Sie bereiten sich auf das Array alle (Fälle zählen) Zeiger auf Strings zu halten, aber Sie sind reserviert nur Speicher für einen String. Sie müssen, dass für jede Saite tun, also Fälle. Um die Dinge einfach in Bezug auf die „dynamische Speicherzuweisung“ Lektion zu halten, empfehle ich es, so zu tun. char* array[cases][10000]; Dass Sie Fälle Saiten 10k Zeichen gibt

Sie wahrscheinlich auch nicht wollen, getrennte Zeiger auf Ihre Array-Elemente haben. Dies beginnt Sinn zu machen, wenn Sie Elemente eines Arrays sortieren wollen, wenn diese Elemente sind größer als die Zeiger selbst. In diesem Fall ist Ihr Gewinn in der Leistung nicht verschieben (kopieren) große Stücke haben, aber nur die Zeiger (in der Regel 4 Bytes). In Ihrem Fall ist ein int auch 4 Bytes lang. Und Sie nicht sortieren trotzdem:)

scanf() ist gefährlich, gelinde gesagt. In Ihrer zweiten Anwendung, es weisen Sie eine Zeichenfolge an die Adresse des Arrays zu schreiben. Dies scheint ein einfacher Fehler zu sein, aber kann zu vielen Problemen führen. Wahrscheinlich wollen Sie es auf diese Weise zu tun: scanf("%d", &array[i]); (Leider habe ich nicht einen Compiler zur Hand, also bin ich nicht 100% sicher). Drop die nächste Zeile:)


Frage zu Markdown-Spezialisten: Warum ist es so verdammt unmöglich LISTEN hat kombiniert mit CODE-Blöcken

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top