Stack czy Heap. Co lepsze i dlaczego?

0

Witam.
Ostatnio mnie nurtuje jedno pytanie.
Ostatnio poznałem mallocka w C. Który przydziela pamięć z Heap.
Ale można normalnie i może łatwiej, żeby sam kompilator przydzielał pamięć. Która jest przechowywana na stosie.
Ale teraz pytanie do was, co jest lepsze? Czy teraz kiedy poznałem Heap, warto przenosić wszystkie zmienne na Heap ze Stacka?
Wiem, że się używa Heap zamiast Stacka przy dużych tablicach. Ale czy warto tak robić z każdą zmienną?
A może polecacie jakieś inne rozwiązanie w C?
Ogólnie dążę do tego, żeby mieć pełną kontrolę nad pamięcią w moim programie. Tzn kiedy ona już jest zbędna nie używana mam ją zamiar uwolnić. Może to zwiększy szybkość programu.

0

O ile to tylko możliwe, dane powinny być alokowane na stosie. Alokacja na stosie jest szybsza a pamięć automatycznie zwalniania w momencie wyjścia danych z zasięgu.

1

Wiem, że się używa Heap zamiast Stacka przy dużych tablicach. Ale czy warto tak robić z każdą zmienną?

Musisz się dobrze zastanowić, jakie jest ryzyko przepełnienia stosu. Generalnie, jeśli masz np funkcję rekurencyjną lub zestaw funkcji które siebie nawzajem wywołują i będziesz alokował dużo na stosie, to jest duże ryzyko przepełnienia stosu. A to wywala aplikację totalnie (a przynajmniej jeden wątek, nie znam się dokładnie na C/ C++). Normalne jest, że typy podstawowe, małe struktury, wskaźniki, czy ogólnie małe obiekty alokuje się na stosie, czyli jako zmienne lokalne. Jak jest coś większego, to alokuje się na stercie.

Alokacja na stercie jest dużo wolniejsza od alokacji na stosie (w ogólności). Alokacja na stosie to tylko przesunięcie wskaźnika stosu (tzn ekwiwalent operacji dodawania/ odejmowania). Alokacja na stercie to już zabawa w różne struktury danych, odwołania do jądra systemu (czasami), synchronizacja (w tymże jądrze), itd Przy alokacji większych obszarów pamięci ten narzut się jednak amortyzuje.

O ile to tylko możliwe, dane powinny być alokowane na stosie. Alokacja na stosie jest szybsza a pamięć automatycznie zwalniania w momencie wyjścia danych z zasięgu.

No i właśnie ten zasięg to jest czasem problem. Jeżeli z funkcji zwracamy wskaźnik/ referencję do czegoś, to to coś nie może być zaalokowane na stosie, bo przecież po wyjściu z funkcji zostanie usunięte. Dlatego jeśli zwracamy wskaźnik/ referencję do czegokolwiek co utworzyliśmy w funkcji, to musimy to utworzyć na stercie.

0
Wibowit napisał(a):

No i właśnie ten zasięg to jest czasem problem. Jeżeli z funkcji zwracamy wskaźnik/ referencję do czegoś, to to coś nie może być zaalokowane na stosie, bo przecież po wyjściu z funkcji zostanie usunięte. Dlatego jeśli zwracamy wskaźnik/ referencję do czegokolwiek co utworzyliśmy w funkcji, to musimy to utworzyć na stercie.

Jeżeli zwracany jest wskaźnik lub referencja to tak, ale dane można zwracać także przez wartość.

0

Rozumiem za i przeciw. Może jest jeszcze inna forma przydzielania pamięci?

0

rejestr procesora. Register

1 użytkowników online, w tym zalogowanych: 0, gości: 1