Menu
Coddy logo textTech

Стек и куча

Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 12 из 104.

Программы на C++ используют две основные области памяти: стек и кучу. Понимание того, где находятся ваши объекты, имеет решающее значение для написания эффективного кода без ошибок.

Стек — это быстрая автоматическая память. Переменные, объявленные внутри функций, живут здесь и автоматически уничтожаются, когда они выходят из области видимости.

void example() {
    int x = 10;           // Выделение в стеке
    Player player;        // Выделение в стеке — уничтожается автоматически
}   // x и player уничтожаются здесь

Куча — это более объемная, но более медленная память, которой вы управляете вручную. Объекты в куче сохраняются до тех пор, пока вы явно их не удалите.

void example() {
    Player* player = new Player();  // Выделение в куче
    // player существует до тех пор, пока не будет удален
    delete player;                   // Требуется ручная очистка
}

Ключевые различия:

СтекКуча
Быстрое выделение памятиБолее медленное выделение памяти
Ограниченный размерБольшая емкость
Автоматическая очисткаТребуется ручная очистка
Объекты фиксированного размераОбъекты динамического размера

Используйте выделение памяти в стеке для небольших, кратковременных объектов. Используйте выделение памяти в куче, когда объекты должны существовать дольше своей области видимости или когда их размер определяется во время выполнения.

Забывание об освобождении памяти в куче приводит к утечкам памяти, распространенному источнику ошибок в программах на C++.

challenge icon

Задание

Легко

Давайте изучим разницу между стековой и кучевой памятью, создав простой класс Counter, который отслеживает, как создаются и уничтожаются объекты.

Вы создадите два файла для организации вашего кода:

  • Counter.h: Определите класс Counter с приватным атрибутом name (string). Включите конструктор, который принимает имя и выводит "Creating: <name>", и деструктор, который выводит "Destroying: <name>". Добавьте метод getName() для возврата имени счетчика.
  • main.cpp: Продемонстрируйте распределение памяти как в стеке, так и в куче. Прочитайте имя из входных данных, затем:
    • Создайте объект Counter в стеке, используя это имя
    • Создайте объект Counter в куче с именем "HeapCounter"
    • Выведите имена обоих счетчиков в формате "Stack: <name>" и "Heap: <name>"
    • Удалите объект, созданный в куче, чтобы предотвратить утечку памяти

Обратите внимание, как сообщения конструктора и деструктора появляются в разном порядке в зависимости от того, когда вы создаете и удаляете каждый объект. Объект в стеке будет автоматически уничтожен по завершении main(), в то время как объект в куче должен быть удален явно.

Подключите ваш заголовочный файл в main.cpp с помощью #include "Counter.h".

Шпаргалка

Программы на C++ используют две основные области памяти: стек и кучу.

Стек — это быстрая автоматическая память. Переменные, объявленные внутри функций, живут здесь и автоматически уничтожаются при выходе из области видимости:

void example() {
    int x = 10;           // Выделение в стеке
    Player player;        // Выделение в стеке — уничтожается автоматически
}   // x и player уничтожаются здесь

Куча — это более объемная, но медленная память, которой вы управляете вручную. Объекты в куче сохраняются до тех пор, пока вы явно их не удалите:

void example() {
    Player* player = new Player();  // Выделение в куче
    // player существует до тех пор, пока не будет удален
    delete player;                   // Требуется ручная очистка
}

Ключевые различия:

СтекКуча
Быстрое выделениеБолее медленное выделение
Ограниченный размерБольшая емкость
Автоматическая очисткаТребуется ручная очистка
Объекты фиксированного размераОбъекты динамического размера

Используйте выделение в стеке для небольших, кратковременных объектов. Используйте выделение в куче, когда объекты должны существовать дольше своей области видимости или когда их размер определяется во время выполнения. Если забыть удалить память в куче, это приведет к утечкам памяти.

Попробуйте сами

#include <iostream>
#include <string>
#include "Counter.h"

using namespace std;

int main() {
    // Считать имя из входных данных
    string inputName;
    cin >> inputName;

    // TODO: Создать объект Counter в стеке, используя inputName

    // TODO: Создать объект Counter в куче с именем "HeapCounter"

    // TODO: Вывести имя счетчика в стеке в формате "Stack: <name>"

    // TODO: Вывести имя счетчика в куче в формате "Heap: <name>"

    // TODO: Удалить счетчик, выделенный в куче, чтобы предотвратить утечку памяти

    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование