close

Přetečení zásobníku

Přejít na navigaci Přejít na hledání

V oblasti výpočetní techniky dochází k přetečení zásobníku , když je na zásobníku vyžadováno příliš mnoho paměti .

V mnoha programovacích jazycích obsahuje zásobník volání omezené množství paměti, které je obvykle opraveno při spuštění programu. Velikost zásobníku závisí na mnoha faktorech, včetně programovacího jazyka, architektury stroje, použití multithreadingu a dostupnosti paměti v systému. Když je v zásobníku použito příliš mnoho paměti , říká se, že dojde k přetečení a dojde k pádu programu [1] . Tato třída chyb je obvykle způsobena jedním ze dvou typů programovacích chyb [2] : nekonečná rekurze a použití velmi velkých proměnných zásobníku.

Nekonečná rekurze

Nejčastější příčinou přetečení zásobníku je rekurze s nadměrnou nebo nekonečnou hloubkou.

Jazyky, které implementují techniku ​​tail rekurze , jako je jazyk Scheme , umožňují konkrétní nekonečnou rekurzi, kterou lze provádět bez přetečení zásobníku. Je to proto, že volání využívající tail-recursion nevyžadují další zásobník [3] .

Velmi velké proměnné zásobníku

Další hlavní příčinou přetečení zásobníku je pokus o přidělení více paměti, než je v zásobníku k dispozici. To se stane, když vytvoříte velmi velké pole lokálních proměnných . Z tohoto důvodu by pole větší než několik kilobajtů měla být alokována dynamicky , spíše než je alokovat jako lokální proměnné [4] .

Příčiny, které mohou snížit dostupnou velikost zásobníku a tím zvýšit pravděpodobnost přetečení zásobníku

Přetečení zásobníku je spojeno se vším, co snižuje efektivní velikost zásobníku programu .

Například program spuštěný jako jedno vlákno může fungovat správně, ale pokud stejný program běží s více vlákny, dojde k selhání programu , protože mnoho programů, které používají vlákna, má pro každé vlákno k dispozici menší zásobník než program. nepoužívá vlákna.

Podobně těm, kteří studují vývoj jádra , se doporučuje nepoužívat rekurzivní algoritmy a velmi velké vyrovnávací paměti v zásobníku [5] [6] .

Příklady v jazyce C / C ++

Nekonečná rekurze s jednou funkcí

 void f () {  
   f ();
 }
 int main ( void ) {  
   f ();
   návrat 0 ; 
 }

Tento úryvek kódu volá funkci f() a ta f()zase volá sama sebe, čímž generuje nekonečnou rekurzi.

Nekonečná rekurze se dvěma funkcemi

 void f ( void ); void g ( void );  
  
 
 int main ( void ) {  
   f ();
  
   návrat 0 ; 
 }
 
 void f ( void ) {  
   g ();
 }
 
 void g ( void ) {  
   f (); }  
 

Funkce f()a funkce se g()navzájem volají nepřetržitě, dokud nedojde k přetečení zásobníku.

Proměnná v zásobníku je příliš velká

 int main ( void ) {  
   dvojité n [ 10000000 ]; návrat 0 ;  
    
 }

Pole deklarované v tomto fragmentu kódu vyžaduje více paměti, než je dostupné v zásobníku, což způsobuje přetečení zásobníku.

Poznámky

  1. ^ James Craig Burley, Používání a portování GNU Fortran , na sunsite.ualberta.ca , 1. června 1991 (archivováno z originálu 5. října 2012) .
  2. ^ Kalev Danny, Understanding Stack Overflow , devx.com , 5. září 2000.
  3. ^ An Introduction to Scheme and its Implementation , na federated.com , 19. února 1997 (z originálu archivováno 10. srpna 2007) .
  4. ^ Howard Feldman, Modern Memory Management, Part 2 , onlamp.com , 23. listopadu 2005. Získáno 10. listopadu 2009 (z originálu archivováno 20. září 2012) .
  5. ^ Průvodce programováním jádra: Tipy pro výkon a stabilitu , na adrese developer.apple.com , Apple Inc. , 7. listopadu 2006 (z originálu archivováno 7. prosince 2008) .
  6. ^ Randy Dunlap, Linux Kernel Development: Getting Started ( PDF ), na xenotime.net , 19. května 2005 (z originálu archivováno 27. února 2012) .

Související položky