Pamięć stosu a sterty
Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 12 z 104.
Programy w C++ korzystają z dwóch głównych obszarów pamięci: stosu i sterty. Zrozumienie, gdzie znajdują się obiekty, ma kluczowe znaczenie dla pisania wydajnego kodu wolnego od błędów.
Stos to szybka pamięć zarządzana automatycznie. Zmienne zadeklarowane wewnątrz funkcji znajdują się tutaj i są automatycznie niszczone, gdy wychodzą poza zakres.
void example() {
int x = 10; // Alokacja na stosie
Player player; // Alokacja na stosie - niszczony automatycznie
} // x i player są tutaj niszczoneStos to większa, ale wolniejsza pamięć, którą zarządzasz ręcznie. Obiekty na stercie istnieją, dopóki ich jawnie nie usuniesz.
void example() {
Player* player = new Player(); // Alokacja na stercie
// player istnieje, dopóki nie zostanie usunięty
delete player; // Wymagane ręczne zwolnienie pamięci
}Najważniejsze różnice:
| Stos | Sterta |
|---|---|
| Szybka alokacja | Wolniejsza alokacja |
| Ograniczony rozmiar | Duża pojemność |
| Automatyczne czyszczenie | Wymagane ręczne czyszczenie |
| Obiekty o stałym rozmiarze | Obiekty o dynamicznym rozmiarze |
Używaj alokacji na stosie dla małych obiektów o krótkim czasie życia. Używaj alokacji na stercie, gdy obiekty muszą istnieć dłużej niż ich zakres lub gdy ich rozmiar jest określany w czasie działania programu.
Zapominanie o zwalnianiu pamięci sterty powoduje wycieki pamięci, które są częstym źródłem błędów w programach C++.
Wyzwanie
ŁatwyPrzyjrzyjmy się różnicy między pamięcią stosu i sterty, tworząc prostą klasę Counter, która śledzi, kiedy obiekty są tworzone i niszczone.
Utwórz dwa pliki, aby uporządkować swój kod:
Counter.h: Zdefiniuj klasęCounterz prywatnym atrybutemname(string). Dodaj konstruktor, który przyjmuje nazwę i wyświetla"Creating: <name>", oraz destruktor, który wyświetla"Destroying: <name>". Dodaj metodęgetName(), która zwraca nazwę licznika.main.cpp: Zademonstruj alokację zarówno na stosie, jak i na stercie. Wczytaj nazwę z wejścia, a następnie:- Utwórz obiekt
Counteralokowany na stosie, używając tej nazwy - Utwórz obiekt
Counteralokowany na stercie o nazwie"HeapCounter" - Wyświetl obie nazwy liczników w formacie
"Stack: <name>"i"Heap: <name>" - Usuń licznik alokowany na stercie, aby zapobiec wyciekowi pamięci
- Utwórz obiekt
Obserwuj, w jakiej kolejności pojawiają się komunikaty konstruktora i destruktora, zależnie od tego, kiedy tworzysz i usuwasz każdy obiekt. Obiekt na stosie zostanie automatycznie zniszczony po zakończeniu działania main(), natomiast obiekt na stercie trzeba jawnie usunąć.
Dołącz plik nagłówkowy w main.cpp za pomocą #include "Counter.h".
Spróbuj swoich sił
#include <iostream>
#include <string>
#include "Counter.h"
using namespace std;
int main() {
// Odczytaj nazwę z wejścia
string inputName;
cin >> inputName;
// TODO: Utwórz obiekt Counter na stosie, używając inputName
// TODO: Utwórz obiekt Counter na stercie o nazwie "HeapCounter"
// TODO: Wypisz nazwę obiektu Counter ze stosu w formacie "Stack: <name>"
// TODO: Wypisz nazwę obiektu Counter ze sterty w formacie "Heap: <name>"
// TODO: Usuń obiekt Counter ze sterty, aby zapobiec wyciekowi pamięci
return 0;
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneBudowanie i kompilacja C++Pliki nagłówkowe i pliki źródłowePrzestrzenie nazw i zakresWprowadzenie do programowania obiektowego w C++Klasy a obiektyWskaźnik „this”Metody (funkcje składowe)Atrybuty (składowe danych)Podstawy konstruktorów i destruktorówPowtórzenie – prosty kalkulator4Właściwości klas
Elementy instancji a elementy statyczneGettery i setteryStałe funkcje składoweSłowo kluczowe mutableMetody i zmienne statyczneFunkcje i klasy zaprzyjaźnionePodsumowanie – menedżer konta bankowego7Dziedziczenie
Podstawy dziedziczeniaPoziomy dostępu w dziedziczeniuKolejność wywołań konstruktora i destruktoraNadpisywanie metodFunkcje wirtualne i VTableWielokrotne dziedziczenieDziedziczenie wirtualnePowtórzenie — hierarchia pracowników2Zarządzanie pamięcią
Pamięć stosu a stertyWskaźniki i referencjePamięć dynamiczna (new/delete)Inteligentne wskaźniki w C++RAII w C++Podsumowanie — menedżer tablicy dynamicznej5Hermetyzacja
Specyfikatory dostępu w C++Specyfikatory dostępu — szczegółowoUkrywanie informacjiStruktura a klasaKlasy zagnieżdżone i wewnętrznePodsumowanie — system ewidencji studentów8Polimorfizm
Polimorfizm czasu kompilacji i wykonaniaPrzeciążanie funkcjiFunkcje wirtualne — powtórkaCzysto wirtualne funkcjeKlasy abstrakcyjneProjektowanie interfejsów w C++Rzutowanie dynamiczne i RTTIPodsumowanie — kalkulator kształtów3Konstruktory i destruktory
Konstruktor domyślnyKonstruktor z parametramiKonstruktor kopiującyKonstruktor przenoszącyListy inicjalizacyjne konstruktoraKonstruktory delegująceDestruktor — szczegółowe omówienieZasada trzech / pięciu / zeraPodsumowanie — klasa String6Przeciążanie operatorów
Wprowadzenie do przeciążania operatorówPrzeciążanie operatorów arytmetycznychPrzeciążanie operatorów porównaniaOperatory strumieniowePrzeciążanie operatora przypisaniaPrzeciążanie operatorów [] i ()Operatory konwersji typówPodsumowanie — klasa Matrix9Szablony
Szablony funkcjiSzablony klasSpecjalizacja szablonówSzablony wariadycznePodstawy SFINAE i cech typówPodsumowanie — kontener generycznyPoćwicz samodzielnie: Kompilator C++ online