Stiva deversare

În calcul , un stack overflow sau overflow stack (engleză, stack overflow ) este un bug cauzat de un proces care, atunci când scrieți într-un stack, este scris în exteriorul spațiului alocat stivei, astfel suprascriind informațiile necesare procesului.

Termenul depășire stivă poate fi aplicat tuturor stivelor . Cu toate acestea, când vorbim despre depășirea stivei, ne referim de obicei la stiva de execuție . Ar fi mai exact atunci să spunem execuția stivei de execuție , dar informaticienii s-au obișnuit să spună pur și simplu exagerarea stivei atunci când contextul indică faptul că stiva despre care vorbim este stiva de execuție.

Restul acestui articol discută despre depășirea stivei de execuție.

În toate limbajele de programare , stiva de execuție conține o cantitate limitată de memorie , de obicei determinată la începutul programului. Dimensiunea stivei de execuție depinde de mulți factori, inclusiv limbajul de programare, arhitectura procesorului , utilizarea procesării cu mai multe fire și cantitatea de RAM disponibilă. Când sunt stocate prea multe informații în stiva de execuție, stiva debordează și suprascrie zonele de program din afara stivei. Se spune apoi că există o revărsare a stivei sau o execuție a revărsării stivei. Acest lucru duce de obicei la o întrerupere a programului .

Principalele cauze ale revărsării stivei de execuție

O depășire a stivei de execuție este de obicei cauzată de una dintre următoarele două erori de programare :

Recursivitate infinită

Cea mai frecventă cauză de revărsare a stivei este o recursiune prea profundă sau infinită.

Rețineți că recursivitatea profundă sau chiar infinită nu provoacă întotdeauna o revărsare a stivei. Într-adevăr, unele limbi, cum ar fi Scheme , permit un fel de recursivitate infinită, recursiunea terminală (în engleză, tail recursion ) fără preaplin de stivă. Pentru a face acest lucru, aceste limbaje transformă recursiunea în iterație , eliminând astfel utilizarea stivei de execuție.

Exemple de recursivitate infinită

Recursivitate infinită cu o singură funcție (în limbaj C )

void a() { a(); } int main() { a(); return 0; }

În exemplul anterior, programul începe execuția în main()care apelează funcția a(). Pe măsură ce funcția se a()numește singură, aceasta creează o buclă infinită.

Recursivitate infinită cu două funcții (în limbaj C)

void f(); void g(); int main() { f(); return 0; } void g() { f(); } void f() { g(); }

Programul își începe execuția în main(), care apelează funcția f(). Apoi funcțiile f()și se g()apelează reciproc până când stiva se revarsă.

Alocarea variabilelor prea mari în stivă

Cealaltă cauză majoră a depășirii stivei este o încercare de a aloca mai mult spațiu pe stivă decât poate stiva stiva. Acesta este de obicei rezultatul declarării variabilelor locale care necesită prea multă memorie. Din acest motiv, tablourile mai mari de câțiva kilobyți ar trebui să fie întotdeauna alocate dinamic, mai degrabă decât ca variabilă locală.


Exemplu de alocare a variabilelor prea mari în stivă int main() { double n[10000000]; }

A declarat matrice consumă mai multă memorie decât este disponibilă pe stivă.

Situații agravante de depășire a stivei de execuție

Depășirile stivei de execuție sunt agravate de orice lucru care reduce dimensiunea stivei. De exemplu, un program fără procesare cu mai multe fire poate funcționa bine, dar de îndată ce procesarea cu mai multe fire este activată, același program poate ajunge într-o stare de revărsare a stivei. Acest lucru se datorează faptului că majoritatea programelor cu fire de execuție au mai puțin spațiu de stivă per thread decât același program wireless pentru stiva sa unică .

Referințe

  1. (în) Burley, James Craig, Utilizarea și Portarea GNU Fortran  " , 1 st iunie 1991.
  2. (în) Danny Kalev, „  Understanding Stack Overflow  ” , 5 septembrie 2000.
  3. (în) „  Introducere în schemă și implementarea sa  ” , 19 decembrie 1997.
  4. (în) Feldman, Howard, „  Modern Memory Management, Part 2  ” , 23 noiembrie 2005.

Vezi și tu

Articole similare