Domanda

Con il seguente pezzo di codice, ottengo un risultato molto strano. Perché il valore dell'ultimo elemento sovrascrive tutti gli elementi dell'array precedenti? Ho il sospetto che ci sia un problema più grande di un semplice problema immmediate.

#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

Nessuna soluzione corretta

Altri suggerimenti

Il risultato qui è la linea array[i] = &num; si sta impostando il valore dell'elemento array[i] all'indirizzo dell'array num; poiché array è un array di caratteri, ho il sospetto che è troncando il tuo indirizzo di matrice num, e il byte di ordine inferiore accade solo per essere un 3.

Tuttavia. Detto questo, il vostro char num [1000000] è forma orribile, e non si deve fare questo, a tutti. Allocare sul mucchio, e scegliere un numero minore, per l'amor del cielo. Inoltre, lo scanf ( "% s", & num) non saranno in realtà darà quello che vuoi. Ecco un suggerimento; utilizzare un ciclo getc () per leggere i numeri; questo evita la necessità di fare qualsiasi preallocazione di un array per scanf ().

E 'perché si sta mettendo in ogni indice dell'array lo stesso indirizzo (l'indirizzo del char num [1000000];).

E 'un errore che vi condurrà alla allocazione dinamica (calloc, malloc, nuovo, ecc).

Cheers!

All'interno del vostro primo ciclo, si dovrebbe essere (ma non lo sono) a scrivere ogni ingresso in un elemento diverso della matrice num; invece sei sempre scrivendo nello stesso posto, vale a dire per &num.

char * array [casi];

Questa è assegnato al momento della compilazione, non in fase di esecuzione. E i casi non è inizializzata (anche se penso che si desidera lavorare in modo dinamico in ogni caso.) Così si sia bisogno di preallocare la memoria, o acquisire familiarità con la famiglia malloc delle funzioni di libreria.

Sostituire

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

con

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;
}

per la scansione di ogni stringa nel primo spazio disponibile in num[], e impostare il successivo elemento di array[] punti al successivo spazio disponibile. Ora il vostro printf() delle corde funzionerà. L'originale è stato a scansione ogni stringa nella inizio di num[].

Nota:.. scanf() con %s disadorna è così male come gets(), perché mette alcun limite alla quantità di dati che verranno slurped a non utilizzare nel codice vero e proprio

Sostituire

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

con

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

per stampare in realtà gli indirizzi memorizzati nella a[], piuttosto che gli indirizzi degli elementi di a[]. Il cast è necessario perché %p si aspetta un puntatore-tovoid quindi è necessario fornire uno.

Questo è il codice che è fisso:

#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;
}

È possibile anche utilizzare

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

che è un po 'sulla difensiva. Non so il motivo per cui è necessario 100000. È possibile farlo in modo dinamico utilizzando malloc. Ciò comporta più lavoro, ma è molto robusto.

Ciò che è hapenning nel codice è che si memorizza la stringa% s per l'indirizzo del num che non cambia, allora si assegna array [i] elemento a quell'indirizzo. L'assegnazione in C non è altro quindi memorizzare il riferimento, non memorizzare l'elemento itself- questo sarebbe spreco di spazio. Così come tutti gli elementi insieme di punti per l'indirizzo (solo memorizzare il riferimento), il valore del cambio indirizzo, quindi così fa il riferimento, è per questo che tutti stanno cambiando a 2 (non 3 come lei ha dichiarato nel tuo post).

E 'per queste cose che C ++ sembra fatto. analisi input dell'utente e allocazioni dinamiche sono fatte in modo più sicuro, e in una brezza. Non riesco a pensare a un sistema in cui hai quel tipo di interfaccia utente, dove non si poteva passare a C ++.

Naturalmente, se questo è solo un estratto di test da altro codice che soffre del problema, allora naturalmente ...


Il tuo codice soffre di diversi errori comuni per i principianti C e le cose che non dovrebbe essere fatto in questo modo al giorno d'oggi.

Se ho capito bene, si desidera salvare le stringhe di input utente sereval (l'output esempio è un po 'fuorviante, perché si mostra solo i numeri).

Vi state preparando la matrice per contenere tutti i casi (contare) i puntatori alle stringhe, ma siete solo riservando memoria per una stringa. Hai bisogno di fare che per ogni stringa, quindi i casi. Per mantenere le cose semplici in termini di lezione "dinamica allocazione della memoria", vi consiglio di fare in questo modo:. char* array[cases][10000]; Che ti dà casi stringhe di caratteri 10k

Probabilmente, inoltre, non si vuole avere puntatori separati ai vostri elementi di matrice. Questo comincia ad avere senso se si desidera ordinare gli elementi di un array quando tali elementi sono più grandi delle sé puntatori. In tal caso, il guadagno in termini di prestazioni è di non avere mossa (copia) pezzi di grandi dimensioni, ma solo i puntatori (generalmente 4 byte). Nel tuo caso, un int è anche lungo 4 byte. E non ordinare in ogni caso:)

scanf() è pericoloso, per non dire altro. Nella tua seconda domanda, si indica per scrivere una stringa per l'indirizzo della matrice. Questo sembra essere un semplice errore, ma può portare a molti problemi. Probabilmente si vuole fare in questo modo: scanf("%d", &array[i]); (Purtroppo, non ho un compilatore a portata di mano, quindi sono sicuro al 100%). cadere la riga successiva:)


Domanda agli specialisti Markdown:? Perché è così dannatamente impossibile avere elenchi combinati con il codice di blocchi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top