Stiva deversare

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Notă despre dezambiguizare.svg Dezambiguizare - Dacă sunteți în căutarea site-ului Q&A cu același nume, consultați Stack Overflow (site) .

În calcul , o depășire a stivei apare atunci când este necesară prea multă memorie pe stivă .

În multe limbaje de programare , stiva de apeluri conține o cantitate limitată de memorie, de obicei fixată la pornirea programului. Dimensiunea stivei depinde de mulți factori, inclusiv limbajul de programare, arhitectura mașinii, utilizarea multithreading-ului și disponibilitatea memoriei în sistem. Când se folosește prea multă memorie în stivă, se spune că are loc o revărsare și are loc o blocare a programului [1] . Această clasă de erori este de obicei cauzată de unul dintre cele două tipuri de erori de programare [2] : recursivitate infinită și utilizarea unor variabile de stivă foarte mari.

Recursivitate infinită

Cea mai frecventă cauză a revărsării stivei este recursivitatea cu adâncime excesivă sau infinită.

Limbajele care implementează tehnica recursivității cozii , cum ar fi limbajul Scheme , permit o anumită recursivitate infinită care poate fi efectuată fără depășirea stivei. Acest lucru se datorează faptului că apelurile care utilizează recursivitatea în coadă nu necesită spațiu suplimentar în stivă [3] .

Variabile de stivă foarte mari

Cealaltă cauză majoră a depășirii stivei este o încercare de a aloca mai multă memorie decât este disponibilă în stivă. Acest lucru se întâmplă atunci când creați o gamă foarte mare de variabile locale . Din acest motiv, tablourile mai mari de câțiva kilobyți ar trebui alocate dinamic, mai degrabă decât alocarea lor ca variabile locale [4] .

Cauze care pot reduce dimensiunea stivei disponibile și, astfel, pot face ca deversarea stivei să fie mai probabilă

Depășirile stivei sunt agravate de orice lucru care reduce dimensiunea efectivă a stivei unui program.

De exemplu, un program care rulează ca un singur fir poate funcționa corect, dar dacă același program rulează cu mai multe fire, se produce un blocaj al programului, deoarece multe programe care utilizează fire au o stivă mai mică disponibilă pentru fiecare fir decât un program. nu folosește fire.

În mod similar, cei care studiază dezvoltarea nucleului sunt sfătuiți să nu utilizeze algoritmi recursivi și tampoane foarte mari în stivă [5] [6] .

Exemple în C / limbajul C ++

Recursivitate infinită cu o singură funcție

 nul f () {
   f ();
 }
 int main ( nul ) {
   f ();
   retur 0 ;
 }

Acest fragment de cod numește funcția f() , iar funcția f() la rândul său se numește singură, generând astfel o recursivitate infinită.

Recursivitate infinită cu două funcții

 void f ( nul ); 
 nul g ( nul );
 
 int main ( nul ) {
   f ();
  
   retur 0 ;
 }
 
 void f ( nul ) {
   g ();
 }
 
 void g ( nul ) {
   f ();  
 }

Funcția f() și funcția g() se apelează reciproc până când se produce depășirea stivei.

Variabilă excesiv de mare în stivă

 int main ( nul ) {
   dublu n [ 10000000 ]; 
   retur 0 ;
 }

Matricea declarată în acest fragment de cod necesită mai multă memorie decât este disponibilă în stivă, provocând astfel o revărsare a stivei.

Notă

  1. ^ James Craig Burley, Utilizarea și portarea GNU Fortran , pe sunsite.ualberta.ca , 1 iunie 1991 (arhivat din original la 5 octombrie 2012) .
  2. ^ Kalev Danny, Understanding Stack Overflow , devx.com , 5 septembrie 2000.
  3. ^ An Introduction to Scheme and its Implementation , pe federated.com , 19 februarie 1997 (arhivat din original la 10 august 2007) .
  4. ^ Howard Feldman, Modern Memory Management, Partea 2 , pe onlamp.com , 23 noiembrie 2005.
  5. ^ Ghid de programare a nucleului: sfaturi de performanță și stabilitate , la developer.apple.com , Apple Inc. , 7 noiembrie 2006 (arhivat din original la 7 decembrie 2008) .
  6. ^ Randy Dunlap, Linux Kernel Development: Getting Started ( PDF ), pe xenotime.net , 19 mai 2005 (arhivat din original la 27 februarie 2012) .

Elemente conexe