Stakoverløb
Ved databehandling opstår et stak-overløb , når der kræves for meget hukommelse på stakken .
I mange programmeringssprog indeholder opkaldsstakken en begrænset mængde hukommelse, normalt fast ved programstart. Størrelsen af stakken afhænger af mange faktorer, herunder programmeringssproget, maskinens arkitektur , brugen af multithreading og tilgængeligheden af hukommelse i systemet. Når der bruges for meget hukommelse i stakken , siges det, at der opstår et overløb , og at der opstår et programnedbrud [1] . Denne klasse af fejl er normalt forårsaget af en af to typer programmeringsfejl [2]: uendelig rekursion og brug af meget store stakvariabler.
Uendelig rekursion
Den mest almindelige årsag til et stackoverløb er rekursion med for stor eller uendelig dybde.
Sprog, der implementerer halerekursionsteknikken , såsom Scheme -sproget , tillader en bestemt uendelig rekursion, der kan udføres uden stak-overløb. Dette skyldes, at opkald, der bruger hale-rekursion, ikke kræver yderligere stakplads [3] .
Meget store stakvariabler
Den anden hovedårsag til stak-overløb er et forsøg på at allokere mere hukommelse, end der er tilgængeligt på stakken. Dette sker, når du opretter et meget stort udvalg af lokale variabler . Af denne grund bør arrays større end nogle få kilobytes tildeles dynamisk i stedet for at allokere dem som lokale variabler [4] .
Årsager, der kan reducere den tilgængelige stakstørrelse og dermed gøre et stackoverløb mere sandsynligt
Stakoverløb forstærkes af alt, der reducerer et programs effektive stakstørrelse .
For eksempel kan et program, der kører som en enkelt tråd , fungere korrekt, men hvis det samme program kører med flere tråde, opstår der et programnedbrud , fordi mange programmer, der bruger tråde, har en mindre stak tilgængelig for hver enkelt tråd end et program. bruger ikke tråde.
Tilsvarende rådes dem , der studerer kerneudvikling , til ikke at bruge rekursive algoritmer og meget store buffere i stakken [5] [6] .
Eksempler i C / C ++ sproget
Uendelig rekursion med én funktion
void f () {
f ();
}
int main ( void ) {
f ();
returnere 0 ;
}
Dette kodestykke kalder funktionen f() , og funktionen f()kalder igen sig selv og genererer derved en uendelig rekursion.
Uendelig rekursion med to funktioner
void f ( void ); void g ( void );
int main ( void ) {
f ();
returnere 0 ;
}
void f ( void ) {
g ();
}
void g ( void ) {
f (); }
Funktionen f()og funktionen g()kalder hinanden kontinuerligt, indtil stakoverløbet opstår.
Variabel i stakken for stor
int main ( void ) {
dobbelt n [ 10000000 ]; returnere 0 ;
}
Det array, der er erklæret i dette kodestykke, kræver mere hukommelse, end der er tilgængeligt på stakken, hvilket forårsager et stackoverløb.
Noter
- ^ James Craig Burley, Using and Porting GNU Fortran , på sunsite.ualberta.ca , 1. juni 1991 (arkiveret fra originalen den 5. oktober 2012) .
- ^ Kalev Danny, Understanding Stack Overflow , devx.com , 5. september 2000.
- ^ An Introduction to Scheme and its Implementation , på federated.com , 19. februar 1997 (arkiveret fra originalen den 10. august 2007) .
- ^ Howard Feldman, Modern Memory Management, del 2 , på onlamp.com , 23. november 2005. Hentet 10. november 2009 (arkiveret fra originalen 20. september 2012) .
- ^ Kernel Programming Guide: Performance and Stability Tips , på developer.apple.com , Apple Inc. , 7. november 2006 (arkiveret fra originalen den 7. december 2008) .
- ^ Randy Dunlap, Linux Kernel Development: Getting Started ( PDF ), på xenotime.net , 19. maj 2005 (arkiveret fra originalen 27. februar 2012) .