Stack overflow: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica |
traduzione dalla versione inglese |
||
Riga 1:
In [[informatica]] uno '''stack overflow''' avviene quando è in uso una quantità troppo elevata di [[Memoria (informatica)|memoria]] nello [[stack]]. In molti [[linguaggi di programmazione]] lo stack delle chiamate contiene una quantità limitata di memoria, che viene fissata di solito all'avvio del programma. La dimensione dello stack dipende da molteplici fattori, inclusi il linguaggio di programmazione, l'[[Architettura (computer)|architettura]] della macchina, l'uso del [[multithreading]], e la disponibilità di memoria nel sistema. Quando viene usata troppa memoria nello stack si dice che avviene un'[[overflow]], e tipicamente come conseguenza di questa situazione si verifica un [[Crash (informatica)|crash]] del programma<ref name="fortran1"> {{cite web
| last = Burley
| first = James Craig
| title = Using and Porting GNU Fortran
| url= http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.95.2/html_node/g77_597.html
| date = 1991-06-01 }}</ref>. Questa classe di [[bug]] solitamente è causata da uno dei due tipi di errori di programmazione<ref name="devx">
{{cite web
| last = Danny
| first = Kalev
| title = Understanding Stack Overflow
| url=http://www.devx.com/tips/Tip/14276
| date = 2000-09-05 }}</ref>.
==Ricorsione infinita==
La causa più comune di uno stack overflow è la profondità eccessiva o una [[ricorsione]] infinita. I linguaggi che implementano la tecnica [[Algoritmo_ricorsivo#Eliminazione_della_ricorsione|tail recursion]], come ad esempio il linguaggio [[Scheme]], permettono una particolare ricorsione infinita che possa essere eseguita senza stack overflow. Questo avviene poiché le chiamate che fanno uso di tail-recursion non richiedono uno spazio aggiuntivo nello stack<ref name="tailRecur">{{cite web
| title = An Introduction to Scheme and its Implementation
| url=http://www.federated.com/~jim/schintro-v14/schintro_73.html
| date = 1997-02-19 }} </ref>
.
==Variabili di stack molto grandi==
L'altra causa principale dello stack overflow è il tentativo di allocare più memoria nello stack di quella che è disponibile. Questo avviene tipicamente quando si crea un [[array]] di variabili locali molto grande. Per questo motivo gli array più grandi di qualche [[kilobyte]] dovrebbero essere allocati dinamicamente anziché allocarli come variabili locali<ref name="onlamp">{{cite web
| last = Feldman
| first = Howard
| title = Modern Memory Management, Part 2
| url=http://www.onlamp.com/pub/a/onlamp/2005/11/23/memory-management-2.html
| date = 2005-11-23 }} </ref>.
Gli stack overflow sono aggravati da qualsiasi cosa riduca la dimensione effettiva dello stack di un programma. Ad esempio un programma che viene eseguito come [[thread]] singolo potrebbe funzionare correttamente, ma se lo stesso programma viene eseguito con thread multipli si verifica un crash del programma. Ciò avviene perché molti programmi che usano i thread hanno a disposizione uno stack più piccolo per ogni singolo thread rispetto ad un programma che non usi i thread. Allo stesso modo, le persone che si avvicinano allo sviluppo di un [[kernel]] sono invitate a non usare algoritmi ricorsivi e [[buffer]] molto grandi nello stack<ref name="apple1">{{cite web
| publisher= [[Apple Inc]].
| title = Kernel Programming Guide: Performance and Stability Tips
| url=http://developer.apple.com/DOCUMENTATION/Darwin/Conceptual/KernelProgramming/style/chapter_5_section_5.html
| date = 2006-11-07 }} </ref><ref name="xenotime">{{cite web
| last = Dunlap
| first = Randy
| title = Linux Kernel Development: Getting Started
| url=http://www.xenotime.net/linux/mentor/linux-mentoring.pdf
| date = 2005-05-19 }} </ref>.
==Esempi nel linguaggio C/C++==
===Ricorsione infinita con una funzione===
<source lang="c">
void f() {
f();
}
int main(void) {
f();
return 0;
}
</source>
Questo frammento di codice invoca la funzione <code>f()</code>, e la funzione <code>f()</code> a sua volta richiama se stessa, generando in tal modo una ricorsione infinita.
===Ricorsione infinita con due funzioni===
<source lang="c">
void f(void);
void g(void);
int main(void) {
f();
return 0;
}
void f(void) {
g();
}
void g(void) {
f();
}
</source>
La funzione <code>f()</code> e la funzione <code>g()</code> si richiamano continuamente a vicenda, finché non si verifica lo stack overflow.
===Variabile nello stack eccessivamente grande===
<source lang="c">
int main(void) {
double n[10000000];
return 0;
}
</source>
L'array dichiarato in questo frammento di codice richiede più memoria di quella disponibile nello stack, causando così uno stack overflow.
==Note==
{{Reflist}}
==Voci correlate==
* [[Heap overflow]]
* [[Buffer overflow]]
[[en:Stack overflow]]
|