2016-07-11 59 views
5

segue è un semplice programma C:dati Memorizzazione (stringa) fuori limite in un array allocato dinamicamente

char *p = (char*)calloc(5,sizeof(char)); 
strcpy(p,"Elephant"); 
printf("String = %s\n", p); 
p[6] = 'D'; 
printf("String = %s\n", p); 

che alloca un array di caratteri su 5 elementi utilizzando calloc() e utilizza strcpy() per copiare una stringa nell'array. Di seguito è riportato l'output:

String = Elephant 
String = ElephaDt 

Chiaramente, ho chiesto solo e quindi curiosi 5 elementi char sapere perché la memoria Gestione sistema operativo mi ha permesso di memorizzare più elementi fuori dai limiti dello spazio assegnato dinamicamente in p . Se mi è stato assegnato solo uno spazio di 5 caratteri, in che modo strcpy() è stato in grado di memorizzare una stringa ancora più grande "Elephant" che ha una lunghezza superiore a 5 caratteri?

+4

C non ha limiti di controllo, il compilatore non si lamenterà (o lo saprà davvero) se si scrive fuori limite. Ciò comporta un comportamento * non definito *, quindi non farlo. –

+0

@Joachim Pileborg "non si lamenterà ... se scrivi fuori limite" è un comportamento definito. Certamente C non specifica il controllo dei limiti, ma un compilatore può utilizzarlo. La scrittura fuori dai limiti è UB. – chux

+0

"perché la memoria del sistema operativo mgmt mi ha permesso di memorizzare più elementi fuori dai limiti dello spazio allocato dinamicamente in p". -> Cosa ti aspettavi che il codice sarebbe stato richiesto di fare in una situazione come questa? – chux

risposta

5

Quando la memoria è allocata, generalmente viene eseguita da un gestore di memoria. Questi spesso allocano pezzi più grandi di memoria dal sistema operativo, quindi li distribuiscono a malloc() e agli amici in parti più piccole.

I 5 byte allocati sono quindi molto probabilmente parte di una porzione più ampia di memoria. Dal momento che hai violato i limiti della tua allocazione, ma non del pezzo più grande, il sistema operativo non interferisce. Può significare, tuttavia, che hai danneggiato altra memoria del tuo programma, sovrascrivendo un'allocazione nelle vicinanze. Può anche significare che hai danneggiato i dati che il gestore della memoria utilizza per tenere traccia della memoria allocata e libera. Ma non è un dato. È semplicemente un comportamento indefinito.

Comportamento non definito non significa che è necessario ottenere un errore di runtime. Può anche significare che non succede niente, o che inizi la WW3, o qualsiasi altra cosa. Non è definito, ma non significa necessariamente un arresto anomalo.

2

Ci si deve abituare se si desidera programmare in C. Ci sono molte cose che si possono fare (ad esempio, accedere ad array fuori limite), ma in realtà, se queste cose violano le regole della lingua, si attiverà undefined behavior.

Non aiuta in effetti anche il compilatore non ti avviserà sempre di questo.

Questo è il modo in cui funziona la lingua, il più delle volte, è necessario essere prudenti per non violare tali regole.

0

Utilizzando strcpy(), verrà copiato il numero di caratteri che si desidera raggiungere nella destinazione definita. Non controlla i limiti dell'array. Continua semplicemente a copiare finché non ha copiato l'intera parola.


Ciò significa che è possibile farlo senza un errore di compilazione. Tuttavia, questo richiama (vedere this link per capirlo), poiché non si può essere sicuri di cosa succede fuori dai limiti della memoria allocata. Nel tuo caso non è successo niente di brutto (in realtà quello che è successo è ciò che volevi accadere) ma non puoi essere sicuro in generale.

-1

La matrice, che si sta allocando dinamicamente, viene allocata dalla memoria Heap. Come @Rudy Velthuis ha menzionato, la memoria di heap viene allocata in grandi blocchi. Pertanto, in uno scenario normale, il tuo programma sta funzionando bene. Ma considera uno scenario, dove c'è una situazione difficile e la maggior parte della memoria del tuo computer è occupata. A quel tempo, c'è un'alta probabilità che i frammenti di memoria di un processo nell'heap risiedano vicino al blocco heap, assegnato al processo.E rendendo la situazione ancora più probabilistica, supponiamo che la matrice venga allocata all'estremità dell'heap, quindi accedendo oltre la fine della memoria allocata, il tuo programma accederà all'heap dell'altro programma.In tal caso, il sistema operativo interverrà, negherà l'accesso al programma e il programma si bloccherà.

Spero che ti aiuti.

+0

Downvoter, indicare le ragioni per le downvoting. –

+0

Il tuo programma, una volta compilato, si comporterà esattamente allo stesso modo in una situazione di memoria stretta o non stretta. – tofro

+0

@tofro, ho descritto uno scenario ipotetico. Inoltre, ho sperimentato personalmente lo stesso. Il programma compilato usando le compilazioni turbo, l'accesso alla memoria oltre i limiti, a volte si è bloccato e talvolta è andato a buon fine. Vorrei poterti mostrare questo eseguibile. –

Problemi correlati