ďťż
 
 
   [C++] Kłopoty z pamięcią
 
 

Tematy

 
    
 

 

 

 

[C++] Kłopoty z pamięcią





Smerf - 07-11-2007 15:38
#include<iostream>
using namespace std;

int main()
{
int tab[1000001];
int tab1[1000001];
int tab2[1000001];
int n;
cin>>n;
} kompiluje się, ale przy uruchomieniu wywala Naruszenie ochrony pamięci.
#include<iostream>
using namespace std;

int main()
{
int tab[1000001];
int tab1[1000001];
int tab2[1000001];
int n;
} kompiluje się i działa

#include<iostream>
#include<vector>
using namespace std;

int main()
{
vector<int> tab(1000001);
vector<int> tab1(1000001);
vector<int> tab2(1000001);
int n;
cin>>n;
} kompiluje się i działa

Ktoś wie o co chodzi?????



cepe - 07-11-2007 16:27
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.

Zrób tak, a będzie dobrze:
#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ę.



ponton - 07-11-2007 16:46
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).



cepe - 07-11-2007 16:52
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ę!



Smerf - 07-11-2007 17:06
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?



ponton - 07-11-2007 17:17
Dokładnie to nie wiem, ale może to (http://pl.wikipedia.org/wiki/Przepełnienie_stosu) pomoże.



phund - 09-11-2007 00:36

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 :)



ponton - 09-11-2007 00:43
Z tego co wiem, jest jakiś limit górny też. 4 GB? Przydałby się ktoś, kto wklei odpowiednie linijki ze źródła kernela i udowodni. ;)



fabix - 09-11-2007 22:34

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. Wcale nie musi tak, być system ogranicza zasoby użytkownika według reguł które można uzyskać tak:
ulimit -a 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.
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • minister.pev.pl

  •  

     


     

     
    Copyright 2003. MĂłj serwis