Menu
Coddy logo textTech

Pamięć dynamiczna (new/delete)

Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 14 z 104.

Skoro rozumiesz już wskaźniki i referencje, wykorzystajmy je do dynamicznej alokacji pamięci. Operatory new i delete pozwalają tworzyć i niszczyć obiekty na stercie w czasie działania programu.

Użyj new, aby przydzielić pamięć i otrzymać wskaźnik do niej:

int* num = new int;        // Przydziel pamięć na pojedynczą liczbę całkowitą
*num = 42;                 // Przypisz wartość za pomocą wskaźnika

Player* player = new Player("Hero");  // Przydziel pamięć na obiekt

Każde new musi mieć odpowiadające mu delete, aby zwolnić pamięć:

delete num;      // Zwalnia pojedynczy obiekt
delete player;   // Wywołuje destruktor, a następnie zwalnia pamięć

W przypadku tablic użyj new[] i delete[]:

int* scores = new int[5];    // Przydziel pamięć na tablicę 5 liczb całkowitych
scores[0] = 100;

delete[] scores;             // Zwolnij pamięć tablicy — zwróć uwagę na nawiasy kwadratowe!

Typowe błędy, których należy unikać:

// Wyciek pamięci – zapomniano użyć delete
int* ptr = new int(10);
ptr = new int(20);    // Utracono dostęp do pierwszego przydzielonego obszaru pamięci!

// Wiszący wskaźnik – użycie po delete
delete ptr;
*ptr = 5;             // Niezdefiniowane zachowanie!

// Niedopasowane delete
int* arr = new int[10];
delete arr;           // Źle! Należy użyć delete[]

Po usunięciu ustaw wskaźniki na nullptr, aby uniknąć ich przypadkowego ponownego użycia. Ręczne zarządzanie pamięcią jest podatne na błędy, dlatego nowoczesny C++ preferuje inteligentne wskaźniki, które omówimy w następnej kolejności.

challenge icon

Wyzwanie

Łatwy

Zbudujmy prosty system przechowywania wiadomości, który demonstruje dynamiczną alokację pamięci za pomocą new i delete.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • MessageBox.h: Zdefiniuj klasę MessageBox, która dynamicznie zarządza tablicą wiadomości. Klasa powinna zawierać:
    • Prywatny wskaźnik do dynamicznie zaalokowanej tablicy ciągów znaków
    • Prywatną liczbę całkowitą śledzącą bieżącą liczbę wiadomości
    • Prywatną liczbę całkowitą przechowującą maksymalną pojemność
    • Konstruktor, który przyjmuje pojemność i alokuje tablicę za pomocą new[]
    • Destruktor, który prawidłowo zwalnia pamięć za pomocą delete[] i wyświetla "MessageBox destroyed"
    • Metodę addMessage(string msg), która dodaje wiadomość, jeśli jest miejsce, zwracając true w przypadku powodzenia lub false, jeśli tablica jest pełna
    • Metodę printAll(), która wyświetla każdą przechowywaną wiadomość w osobnym wierszu
  • main.cpp: Wczytaj z wejścia wartość pojemności i liczbę wiadomości. Następnie wczytaj tyle ciągów znaków z wiadomościami. Utwórz obiekt MessageBox na stercie za pomocą new, dodaj do niego wszystkie wiadomości, wywołaj printAll(), a następnie prawidłowo usuń obiekt MessageBox, aby zwolnić pamięć.

Format danych wejściowych będzie następujący:

  • Pierwszy wiersz: pojemność (liczba całkowita)
  • Drugi wiersz: liczba wiadomości do dodania (liczba całkowita)
  • Kolejne wiersze: jedna wiadomość w każdym wierszu

Pamiętaj: każdemu new musi odpowiadać pasujące delete, a każdemu new[] musi odpowiadać pasujące delete[]. Po usunięciu dobrze jest ustawić wskaźniki na nullptr.

Dołącz plik nagłówkowy w main.cpp za pomocą #include "MessageBox.h".

Spróbuj swoich sił

#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;

int main() {
    int capacity;
    int numMessages;
    
    // Wczytaj pojemność i liczbę wiadomości
    cin >> capacity;
    cin >> numMessages;
    cin.ignore(); // Usuń znak nowej linii po liczbie
    
    // TODO: Utwórz MessageBox na stercie za pomocą new
    
    // TODO: Wczytaj i dodaj wszystkie wiadomości do MessageBox
    for (int i = 0; i < numMessages; i++) {
        string message;
        getline(cin, message);
        // Dodaj wiadomość do MessageBox
    }
    
    // TODO: Wywołaj printAll(), aby wyświetlić wszystkie wiadomości
    
    // TODO: Usuń MessageBox, aby zwolnić pamięć
    // Pamiętaj, aby po usunięciu ustawić wskaźnik na nullptr
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online