Domanda

Scusate se è una domanda da noob :( .

Pezzo di codice C.

int array[5];
int cnt;

for(cnt = 0; cnt <= 10; cnt+=1)
{
      array[cnt] = cnt;
}

Dovrebbe dare un errore, giusto?NO!Funziona bene!Ma perché?Sembra che nella prima riga sia definito un array di dimensione superiore alla doppia (11).Puoi anche accedere all'array da 5 a 10 in un secondo momento.E questo mi confonde.Smette di funzionare quando definisci array[4 o meno] ...

Grazie in anticipo.

È stato utile?

Soluzione

Potrebbe succedere che funzioni con il tuo particolare compilatore e computer, ma non dovresti contarci.

Il comportamento del codice secondo le specifiche del linguaggio C è non definito.Ciò significa che potrebbe fare ciò che speri, o potrebbe causare il crash del tuo computer, o potrebbe causare demoni che ti volano fuori dal naso.

A differenza dei linguaggi di livello superiore come Java e C#, C si fida di te e non esegue controlli espliciti sui limiti degli array.Dovresti essere responsabile e non uscire dai confini dell'array.

Altri suggerimenti

Questo solo "funziona", se la tua definizione di "opere" è sinonimo di "non è ancora andato in crash".

Quello che state vedendo è comportamento non definito , causato da voi l'accesso alla matrice con un indice non valido. comportamento indefinito significa che tutto può succedere, compreso il vostro programma che sembra funzionare correttamente.

"Ma perché è così?"

Perché questo è il modo in cui C è.

limiti di matrice non vengono controllati in fase di esecuzione.

Questo è il "diritto del C"

Mi piace solo far notare che tutto questo è davvero definito. Il vostro esempio "funziona" in questo esempio specifico, perché entrambe le variabili si trovano in pila. Cioè l'indirizzo della cnt è appena sotto la fine della matrice. Quando cnt cnt raggiunge == 5 l'array dichiarazione [cnt] = cnt; non scrive nella memoria dedicata alla matrice, ma solo dopo che, dove l'indirizzo di cnt trovava. E 'solo fortuna che non altera il vostro contatore. Quando cnt> 5 non v'è alcuna memoria cestino e sarà solo scrivere nel "stack vuoto" (non so la parola corretta).

Un altro esempio per illustrare questo:

int main(int ac,char **av)
{
    int a[5];
    int cnt;
    int cnt2=3;

    for(cnt=0;cnt<7;cnt++) {
        a[cnt]=cnt;
        printf("%d %d %d\n", a[cnt], cnt, cnt2);
    }
}

uscita:

0 0 3
1 1 3
2 2 3
3 3 3
4 4 3
5 5 5
6 6 5

Le ultime due operazioni di scrittura del loop sovrascrive i dati pila dopo un [] e possono produrre errori molto confuse. In questo caso il CNT2 viene cestinato.

Array in C non vengono controllati in fase di esecuzione. In altre parole, è possibile "definire" un array di dimensione N e felicemente accedere fuori dell'estremità della matrice vincolato. Se si va fuori alla fine della matrice, allora si avrà cestino di memoria da qualche parte sullo stack (o heap).

Una volta cestinare la memoria da qualche parte, il programma rischia di schiantarsi. Questi incidenti possono essere difficili da rintracciare perché potrebbero bloccarsi lontano da dove realmente invasero la fine della matrice.

In genere quando si dichiara array in C, è meglio utilizzare una sorta di costante o #define per segnare la dimensione della matrice:

#define MAX_ELEMENTS 10
int array[MAX_ELEMENTS];
int cnt;
for(cnt = 0; cnt < MAX_ELEMENTS; cnt+=1) {
   array[cnt] = cnt;
}

Se si va oltre MAX_ELEMENTS nell'assegnazione matrice, si potrebbe sovrascrivere il valore di cnt. Si potrebbe sovrascrivere qualche altra variabile. Tutto dipende dal compilatore e la struttura del codice. Da notare anche l'uso del

I limiti dell'array in C sono non necessariamente controllato in fase di esecuzione.Lo standard lascia gli implementatori liberi di farlo se lo desiderano o meno: questo fa parte di ciò che è non definito.Su un'implementazione con puntatori fat, l'esempio potrebbe effettivamente causare qualche tipo di errore.

Una volta che si esegue fuori la fine dell'array, si sta sovrascrivendo la memoria che il software non si aspetta e corrompere mucchio. È il software può continuare a correre, ma sarà molto instabile!

Dipende da come la memoria dello stack è pieno. Inoltre, sarà lieto di sovrascrivere questi valori e anche leggerli, ma molto probabilmente si sta corrompendo la pila.

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