Ja chyba wiem: w pierwszym przypadku robisz za dużo zmiennych statycznych! i do tego próbujesz ich używać. W drugim przypadku deklarujesz również za dużo ale ich nie używasz więc nie ma naruszenia pamieci, w trzecim przypadku używasz vector'a , który pamieć przydziela dynamicznie więc wszystko jest w porządku.
#include <iostream>
using namespace std;
int main()
{
int *tab = new int[1000001];
int *tab1 = new int [1000001];
int *tab2 = new int[1000001];
int n;
cin>>n;
...
delete [] tab;
delete [] tab1;
delete [] tab2;
return 0;
}
PS: Niczego nie jestem pewien, jak znajdę dowody (w internecie) tego co mi się wydaje to napiszę.
Nie statyczne, tylko automatyczne/lokalne, Paweł. Te są na stosie. Zmienne dynamiczne (malloc() z C i new z C++, którego używa klasa vector) są tworzone na stercie. Podejrzewam, że po prostu stos się przepełnia (adres n jest poza zakresem stosu i stąd segmentation fault).
ponton (Tomek xD): masz rację. Chodziło mi o zmienne automatyczne: te deklarowane lokalnie i globalnie bez przydzielania pamięci za pomocą operatora new. Kiedyś wg google na stos i stertę było przeznaczone 64 KB. Jeśli się to nie zmieniło to tablice zadeklarowane przez Smerfa grubo przekraczają tą liczbę!
Ok, zadeklarowałem na stercie i działa Jeżeli wyrzuciam tab0 z programu to tab[1] i tab[2] mieszczą się na stosie... Więc mam takie pytanka jeszcze: od czego zależy ile danych może być zadeklarowane na stosie? dane na stercie mogą być deklarowane dopóki starczy RAMu?
Smerf pisze:dane na stercie mogą być deklarowane dopóki starczy RAMu?
Kiedyś z ciekawości napisałem program "pożerający" pamięć - w pętli alokował ciągle nowe zasoby. trudno było stwierdzić, ile zajmował pamięci pod koniec, bo system nieźle zamulił... podejrzewam, że zaczęło się przenoszenie danych na swap, ale nie nadążało to za pętlą. W pewnym momencie program po prostu się zakończył - jeśli się nie mylę, to proces został zabity przez kernel jako mało ważny a zajmujący całą dostępną pamięć i chcący jeszcze Więc kiedy osiągniesz kres pamięci, to kernel zacznie zabijać mało ważne według niego procesy w celu odzyskania zasobów dla systemu.
Niech mnie ktoś poprawi, jeśli coś pokręciłem albo podałem nieściśle
Swoją drogą to warto zabezpieczyć system sensownie jako root. Jeśli widzisz po wydaniu powyższego polecenia unlimited to wypadało by to zmienić. Twój system uodporni się na ataki typu Forkbomb. Info tutaj
Uważajcie na zbyt małe limity!
A co do stosu to w każdym kompilatorze daje się zmienić jego rozmiar. Czy to przy kompilacji, czy wręcz podczas uruchamiania programów. Dla gcc mamy -mstack-size=rozmiar.