stack overflow (tsz. stack overflows)
A stack overflow (verem túlcsordulás) egy olyan programhiba, amely akkor fordul elő, ha egy program túl sok memóriát használ a verem (stack) memóriában, és ezzel túllépi az operációs rendszer vagy a futtatókörnyezet által engedélyezett limitet. Ez általában végtelen vagy nagyon mély rekurzió, illetve túl nagy helyi változók használata miatt következik be.
A C++ programok memóriája általában négy fő részre oszlik: 1. Stack (verem) – Lokális változók és függvényhívások tárolására szolgál. 2. Heap (kupac) – Dinamikusan foglalt memória (pl. new
és delete
operátorok). 3. Data segment (adat szegmens) – Statikus és globális változók. 4. Code segment (kódszegmens) – Maga a programkód.
A verem egy LIFO (Last In, First Out) adattároló struktúra, amelyben minden függvényhívás során új keret (stack frame) jön létre a lokális változók és a visszatérési cím tárolására. Ha túl sok függvényhívás történik, a verem túlcsordulhat.
A verem túlcsordulása (stack overflow) akkor következik be, ha: - Egy rekurzív függvény túl sokszor hívja meg önmagát, anélkül hogy visszatérne. - Egy függvény túl nagy lokális változókat foglal a veremben. - Egy program végtelen rekurzióba kerül.
Ha egy rekurzív függvénynek nincs megfelelő kilépési feltétele, akkor folyamatosan hívja önmagát, ami stack overflow-hoz vezet.
#include <iostream>
using namespace std;
void vegtelenRekurzio() {
cout << "Hívás..." << endl;
vegtelenRekurzio(); // Végtelen rekurzió
}
int main() {
vegtelenRekurzio(); // Stack overflow
return 0;
}
🔴 Hiba: A vegtelenRekurzio()
folyamatosan hívja önmagát, és mivel minden egyes hívás új stack frame-et hoz létre, a program végül túlcsordul.
Ha egy függvény túl nagy lokális tömböt foglal, az könnyen stack overflow-hoz vezethet.
#include <iostream>
using namespace std;
void nagyTomb() {
int tomb; // Túl nagy tömb a veremben
cout << "Tömb lefoglalva!" << endl;
}
int main() {
nagyTomb(); // Stack overflow lehetősége
return 0;
}
🔴 Hiba: Az int tomb
egy nagy méretű tömböt foglal, amelyet a verembe próbál helyezni, és ez stack overflow-t okozhat.
A rekurzió során mindig meg kell adni egy kilépési feltételt, hogy a függvény ne fusson végtelenül.
#include <iostream>
using namespace std;
void rekurzivFuggveny(int n) {
if (n == 0) return; // Kilépési feltétel
cout << "Rekurzió: " << n << endl;
rekurzivFuggveny(n - 1);
}
int main() {
rekurzivFuggveny(10); // Nincs stack overflow
return 0;
}
✅ Megoldás: Az n == 0
feltétel miatt a rekurzió véges számú lépés után leáll.
Mindig kilépési feltétellel kell biztosítani, hogy a rekurzió befejeződjön.
Ha egy függvény túl mélyen rekurzál, érdemes iteratív megoldást választani.
n
esetén)int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
🔴 Probléma: fibonacci(50)
esetén rengeteg hívás történik, stack overflow lehetséges.
int fibonacciIterativ(int n) {
int a = 0, b = 1, c;
for (int i = 2; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return b;
}
✅ Megoldás: Iterációval nincs stack overflow.
Ha egy függvénynek nagy tömböket kell kezelnie, érdemes a heap memóriát használni a verem helyett.
void nagyTomb() {
int tomb; // Túl nagy a stack számára
}
🔴 Hiba: A tomb
a veremben tárolódik, és túl nagy.
void nagyTomb() {
int* tomb = new int; // Heap memória használata
delete tomb; // Ne felejtsük el felszabadítani!
}
✅ Megoldás: A tömb a heap memóriában van, így elkerüljük a stack overflow-t.
Bizonyos esetekben szükség lehet a stack memória méretének növelésére.
A stack mérete módosítható a linker beállításaival: - Project Settings → Linker → System → Stack Reserve Size
Vagy használhatod a parancssort:
link /STACK:20000000 program.exe
Ez 20 MB-ra növeli a stack méretét.
A stack mérete módosítható a következő paranccsal:
ulimit -s 100000
Ez a stack méretét 100 MB-ra állítja.
A stack overflow egy veszélyes hiba, amely akkor következik be, ha egy program túl sok memóriát használ a veremben. Elkerülése érdekében: - Mindig használj kilépési feltételt rekurziónál! - Nagy tömbök helyett használd a heap memóriát! - Ha kell, használj iterációt rekurzió helyett! - Ha szükséges, növeld a stack méretét az operációs rendszerben!