2012-05-10 37 views
6

używam VS 2010.
Kiedy uruchomić ten program w trybie debugowania rzuca stosu wyjątku przepełnienia i przedstawia linię rozdziału w chkstk.asm pliku w linii 99.
Ale kiedy uruchomię go w trybie Release, jest OK.
Również, jeśli zmniejszam rozmiar jednej z tablic do 10000, działa to dobrze w debugowaniu. Jaki jest powód?przepełnienie stosu wyjątku w programie głupie

#include <iostream> 

using namespace std; 
int main() 
{ 
    char w[1000001], temp[1000001]; 
    cout<<"Why?"<<endl; 
    return 0; 
} 
+3

Jakie optymalizacje zostały włączone w trybie zwolnienia? Istnieje duża szansa, że ​​kompilator właśnie usuwa tablice. –

+0

możliwy duplikat [Przekroczenia stosu podczas debugowania, ale nie w wydaniu] (http://stackoverflow.com/questions/5670904/stack-overflow-when-debugging-but-not-in-release) –

+0

Czy pytasz "Co to jest? powód przelewu? " Lub "Jaki jest powód zmiany zachowania w różnych trybach kompilacji?" Albo coś innego? –

Odpowiedz

11

Ponieważ stos jest dość mały, w przybliżeniu 1 MB na większości systemów, przepełniasz go dużymi buforami. Aby to naprawić, po prostu przydzielić na stertę w następujący sposób:

#include <iostream> 

using namespace std; 
int main() 
{ 
    char* w = new char[1000001]; 
    char* temp = new char[1000001]; 
    cout<<"Why?"<<endl; 
    delete[] w; 
    delete[] temp; 
    return 0; 
} 
+2

lub użyj 'std :: vector' jak ktoś już zasugerował! –

5

Stos jest dość mały (~ 1MB). Wypełniasz go ogromną liczbą elementów w tych tablicach.

Jeśli potrzebujesz więcej miejsca, spróbuj przydzielić na stercie (które wskaźniki działają).

Dobrym sposobem wdrożenia to z wektorami, które wewnętrznie przechowywanie rzeczy na stercie:

std::vector<char> w (1000001); 
std::vector<char> temp (1000001); 
4

Tablice w automatycznym przechowywania są alokowane na stosie. Przestrzeń stosu jest ograniczona. Gdy miejsce na stosie jest niewystarczające do alokacji zmiennych automatycznych, występuje wyjątek przepełnienia stosu.

Jeśli potrzebujesz dużych tablic, użyj alokacji statycznej lub dynamicznej.

Dla alokacji statycznej przenieś deklaracje na zewnątrz main().

do dynamicznego przydzielania, skorzystaj z poniższego kodu:

char *w = new char[1000001], *temp = new char[1000001]; 
// Work with w and temp as usual, then 
delete[] w; 
delete[] temp; 

Wreszcie, należy rozważyć przy użyciu standardowych pojemników zamiast zwykłych tablic: std::array jest lepsza matryca czy nie trzeba rozmiaru (to jest przydzielona na stosie, i nie rozwiąże to problemu); std::string jest również dobrym kandydatem do zastąpienia macierzy char.

+2

Nie sądzę, że 'std :: array' rozwiąże problem. To * nadal * przydzieli dane na stosie. Spróbuj 'std :: vector'. –

+0

@ Robᵩ Masz rację, nie byłoby! Wspomniałem 'std :: array' jako zamiennik zwykłych tablic, a nie jako sposób na rozwiązanie tego konkretnego problemu. Widzę, jak ta część odpowiedzi może wprowadzać w błąd, więc zredagowałem ją dla jasności. Dzięki! – dasblinkenlight

5

Przydzielasz za dużo rzeczy na stosie; prawdopodobnie w trybie debugowania stos jest bardziej zajęty z powodu różnych kontroli bezpieczeństwa lub celowo jest mniejszy, aby pomóc w wykryciu takich problemów wcześniej. W każdym razie zwiększenie rozmiarów tablic spowoduje przepełnienie stosu nawet w trybie zwolnienia (chyba że kompilator całkowicie je zoptymalizuje).

Głównym problemem jest to, że nie należy przydzielać dużych rzeczy na stosie, który ma dość ograniczony rozmiar (domyślnie 1 MB w systemie Windows z VC++) i powinien być używany tylko w przypadku małych buforów/obiektów. Jeśli potrzebujesz dużych alokacji, zrób je na stercie (z new/malloc), najlepiej za pomocą inteligentnych wskaźników, aby uniknąć wycieków pamięci.

Powiązane problemy