Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Gdzie są przechowywane jakie obiekty?

Ostatnio zmodyfikowano 2015-04-19 18:55
Autor Wiadomość
Kyriet
Temat założony przez niniejszego użytkownika
Gdzie są przechowywane jakie obiekty?
» 2015-04-19 14:28:14
Bez zbędnych wstępów. Proszę zweryfikować, czy dobrze rozumiem.
Program może mieć przydzielone 3 obszary pamięci: stos, stertę i obszar pamięci statycznej.
Program może mieć następujące rodzaje obiektów: automatyczne (lokalne), statyczne, globalne, dynamiczne i tymczasowe (do przekazywania funkcji argumentów przez wartość, zwracanie wartości przez funkcję)

Obiekty automatyczne (lokalne) ---> stos (śmieci)
Obiekty tymczasowe ---> stos
Obiekty statyczne---> obszar pamięci statycznej (inicjalizowane 0)
Obiekty globalne ---> obszar pamięci statycznej (inicjalizowane 0)
Obiekty dynamiczne ---> sterta (śmieci)

Do tego dorzucam zrobiony przez siebie obrazek:
http://forum.miroslawzelent.pl​/?qa=blob​&qa_blobid=13018402523810798412

Jeśli powyższe zapisy są poprawne, to nie jestem w stanie zrozumieć zachowania kompilatora w tej kwestii:

Obszar pamięci statycznej jest stały, rezerwowany na starcie programu i jest OK. (rezerwacja tablicy miliona int'ów jest OK)
A gdy próbuję tablicę miliona int'ów zrobić wewnątrz funkcji, to wyrzuca stack overflow. Przecież kompilator widzi, że będę taką tablicę tworzył. Dlaczego nie postępuje tak jak ze statycznymi, czyli nie rezerwuje pamięci ile potrzeba?. Rozumiem, gdyby był to stos na procesorze, gdzie liczy się każdy bajt i byłby limit, ale przecież sterta i stos siedzą w tym samym miejscu (pamięć operacyjna: RAM), więc:

1. Dlaczego kompilator ustala, że jest dany rozmiar stosu i koniec kropka? Co mu szkodzi go powiększyć?
2. Dlaczego obiektów statycznych nie obowiązuje limit tak jak stosu? Robiąc tablicę miliona int'ów tyle właśnie rezerwowanej jest pamięci. (stos jest przy tym upośledzony)
3. Czy ten stos jest jakiś szybszy od sterty? No bo przecież RAM to RAM.

Słowem: nie rozumiem po co na obiekty automatyczne nakładany jest ten limit ile mogą maksymalnie miejsca zająć.

Pozdrawiam serdecznie społeczność.
P-131132
pekfos
» 2015-04-19 16:09:04
Dlaczego kompilator ustala, że jest dany rozmiar stosu i koniec kropka? Co mu szkodzi go powiększyć?
A skąd wiesz, że za stosem jest nieograniczone wolne miejsce? Adresy związane ze stosem są w zbyt wielu miejscach, by sobie go ot tak przenieść.

Dlaczego obiektów statycznych nie obowiązuje limit tak jak stosu?
Bo jest z góry znany rozmiar?

Czy ten stos jest jakiś szybszy od sterty?
Jest szybszy.
P-131136
Kyriet
Temat założony przez niniejszego użytkownika
» 2015-04-19 16:23:41
Nie chodziło mi o to, aby go w trakcie działania programu powiększyć. Bo testując taki program:
C/C++
#include <iostream>

using namespace std;

int g = 1; //globalna
int h = 1; //globalna
int main()
{
    int a = 10; //lokalna
    int b = 10; //lokalna
    int * c = new int( 1 ); //sterta
    int * d = new int( 1 ); //sterta
    static int e = 1; //statyczna
    static int f = 1; //statyczna
   
    cout << "stos a : " <<& a << endl;
    cout << "stos b : " <<& b << endl;
    cout << "sterta c : " <<&( * c ) << endl;
    cout << "sterta d : " <<&( * d ) << endl;
    cout << "statyczna e : " <<& e << endl;
    cout << "statyczna f : " <<& f << endl;
    cout << "globalna g : " <<& g << endl;
    cout << "globalna h : " <<& h << endl;
    system( "PAUSE" );
    return 0;
}
Widać wyraźnie, że obiekty statyczne i globalne ustawiane są obok siebie, podobnie jak stos. Więc jeśli milion int'ów da się umieścić obok siebie w RAM'ie, obszarze nazwanym "obszar pamięci statycznej", to nie rozumiem, dlaczego nie działa to w przypadku automatycznych obiektów.
Ja na ten moment mam takie przekonanie, że tak jak na obrazku, który wyżej zamieściłem, wszystkie te obszary: stos, sterta, obszar pamięci statycznej, to po prostu kawałki RAM'u inaczej nazwane.


Dlaczego obiektów statycznych nie obowiązuje limit tak jak stosu?
Bo jest z góry znany rozmiar?
Obiekty automatyczne też mają znany rozmiar juz w trakcie kompilacji. Jest tablica miliona int'ów i kompilator widzi, że jej nie zmieści, a nie informuje o błędzie. Dlaczego jej nie zmieści? Bo tak sobie ubzdurał, że (przykładowo) 1 MB na stos?

I też ciekawe jest to, ze stos jest szybszy od obiektów dynamicznych wskazywanych bezpośrednio wskaźnikami. Obiekty automatyczne i dynamiczne siedzą w RAM'ie (czyt. zarówno stos i sterta to tylko wydzielone obszary RAM), więc jak to możliwe, że do jednych komórek jest szybszy dostęp, a do innych wolniejszy?

Chyba że... naszła mnie taka myśl... wierzchołek stosu trzymany jest w rejestrze procesora, ale to dalej nie wyjaśnia "PO CO" kompilator ogranicza jego (stosu) rozmiar.
P-131139
pekfos
» 2015-04-19 16:30:22
Obiekty automatyczne też mają znany rozmiar juz w trakcie kompilacji. Jest tablica miliona int'ów i kompilator widzi, że jej nie zmieści, a nie informuje o błędzie
Nie wie, czy nie zmieści.

ale to dalej nie wyjaśnia "PO CO" kompilator ogranicza jego (stosu) rozmiar.
Musi być ograniczenie. Co za różnica jakie? Jak milion intów przejdzie, to będziesz chciał mieć dwa..
P-131140
Kyriet
Temat założony przez niniejszego użytkownika
» 2015-04-19 16:49:43
Chyba coś powoli łapię...
Bo przez cały czas zadawałem sobie pytanie: "Dlaczego stos nie działa jak pamięć dynamiczna!!! Dlaczego nie rezerwuje sobie pamięci na potrzebę funkcji, a potem ją zwalnia!". Chyba zrozumiałem. Po co kompilator widząc taką tablicę, miałby z automatu robić stos, aby zmieścić tę tablicę. Nie ma pewności, że ta funkcja zostanie w ogóle wywołana. Nie ma pewności, że nie wywoła samej siebie i potrzeba będzie 2 razy tyle... Więc najlepszym rozwiązaniem jest ustalenie pamięci stosu.

Błędnie porównywałem stos do obiektów globalnych i statycznych. A pamięć dla statycznych jest rezerwowana raz, a obiekty automatyczne przy każdym wejściu w zakres lokalny.

Więc zmienię podejście i porównam teraz do obiektów dynamicznych: (jestem już bliski ogarnięcia tego, ale jeszcze trochę brakuje)
Dlaczego obiekty automatyczne nie zachowują się jak obiekty dynamiczne?
To znaczy:
Przy każdym wejściu w funkcję rezerwowana jest dla nich pamięć - tak jakby operatorem
new
.
Nie trzeba byłoby wtedy ustalać żadnego ograniczenia. Napisałeś, że stos jest szybszy od sterty (pamięci dynamicznej). Biorąc taką hipotezę, stos ma sens.

Ostatnia wątpliwość mi pozostała:
Co sprawia, że stos jest szybszy?
P-131142
pekfos
» 2015-04-19 18:37:33
Bo alokowanie czegokolwiek na stosie to zwykle operacja na jednej liczbie w rejestrze, a dynamiczna alokacja musi pytać o pamięć system, a ten musi znaleźć jeszcze odpowiednio duże wolne miejsce. Same wywołania to już wielokrotne alokacje na stosie.
P-131150
Kyriet
Temat założony przez niniejszego użytkownika
» 2015-04-19 18:49:47
To znaczy, że stos, na którym zakładane są obiekty automatyczne, znajduje się w rejestrze procesora?
Jeśli tak, to wszystkie moje wątpliwości właśnie zostaną rozwiązane.
P-131152
pekfos
» 2015-04-19 18:55:45
To znaczy, że stos, na którym zakładane są obiekty automatyczne, znajduje się w rejestrze procesora?
Trzeba nie wiedzieć, co to rejestr procesora, by walnąć taką bzdurę.. W 32/64 bitach zmieści się najwyżej adres szczytu stosu i to się tam właśnie znajduje.
P-131154
« 1 »
  Strona 1 z 1