Выделение в куче с new/delete
Управляйте динамической памятью
«Выделение в куче с new/delete» — бесплатный урок C++ Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Динамическая память с оператором выделения
Оператор new выделяет объект в куче (свободной области памяти) и возвращает указатель на него. Объекты в куче существуют, пока Вы явно не освободите их.
#include <iostream>
int main() {
int* p = new int(42); // heap allocation
std::cout << *p << "\n";
delete p; // release it
}Освобождение с помощью удаления
Каждому вызову new должен соответствовать ровно один вызов delete. Если забыть его, произойдёт утечка памяти; повторный вызов повредит кучу.
#include <iostream>
int main() {
double* d = new double(3.5);
std::cout << *d << "\n";
delete d; // exactly once
}Массивы: выделение и удаление массивов
Для массивов используйте new[] и соответствующий ему delete[]. Смешивание new[] с обычным delete приводит к неопределённому поведению.
#include <iostream>
int main() {
int* arr = new int[3]{1, 2, 3};
for (int i = 0; i < 3; ++i) std::cout << arr[i] << "\n";
delete[] arr; // note the [ ]
}Зачем использовать кучу
Используйте кучу, когда объект должен жить дольше функции, которая его создала, или когда его размер известен только во время выполнения. В остальных случаях выбирайте стек.
Срок жизни объектов в куче управляется вручную
В отличие от стека, куча не освобождает объекты автоматически. Вы точно определяете, когда освободить память, и несёте за это ответственность.
#include <iostream>
int* makeCounter() {
return new int(0); // survives the function
}
int main() {
int* c = makeCounter();
std::cout << *c << "\n";
delete c;
}Присваивайте указателям nullptr после удаления
После удаления присваивайте указателю значение nullptr, чтобы случайное повторное использование приводило к явной ошибке, а не к обращению к освобождённой памяти.
#include <iostream>
int main() {
int* p = new int(9);
delete p;
p = nullptr; // now p is safe to check
if (!p) std::cout << "freed\n";
}Выделение памяти может завершиться неудачей
Если в системе закончилась память, new выбрасывает исключение std::bad_alloc. При очень больших выделениях памяти это вполне возможно.
Буферы размером, известным во время выполнения
Массивы в куче могут использовать размер, вычисленный во время выполнения, — переносимые программы не позволяют делать это с массивами в стеке.
#include <iostream>
int main() {
int n = 5;
int* buf = new int[n];
for (int i = 0; i < n; ++i) buf[i] = i * i;
std::cout << buf[4] << "\n";
delete[] buf;
}Предпочитайте умные указатели
Современный C++ избегает необладающих указателей new/delete. std::unique_ptr и std::make_unique автоматически освобождают память, когда указатель выходит из области видимости.
#include <iostream>
#include <memory>
int main() {
auto p = std::make_unique<int>(42);
std::cout << *p << "\n";
} // freed automaticallyЦена использования кучи
Выделение памяти в куче медленнее, чем в стеке: оно ищет свободный блок и обновляет служебные данные. Частые выделения очень маленьких блоков могут ухудшить производительность.
Сопоставляйте каждому выделению освобождение
Золотое правило: каждому вызову new нужен один вызов delete, а каждому вызову new[] — один вызов delete[]. Ещё лучше поручить это умным указателям.
Быстрая проверка
Проверьте, насколько хорошо Вы поняли выделение памяти в куче.
Итоги
Вы научились выделять память в куче с помощью new/new[] и освобождать её с помощью delete/delete[]. Объекты в куче существуют дольше своей области видимости, но требуют ручной очистки. Сопоставляйте каждому выделению освобождение, обнуляйте освобождённые указатели и в современном коде предпочитайте std::unique_ptr.
Часто задаваемые вопросы
Урок «Выделение в куче с new/delete» бесплатный?
Да — полный текст урока «Выделение в куче с new/delete» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Выделение в куче с new/delete»?
Управляйте динамической памятью Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Выделение в куче с new/delete»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Выделение в стеке
- Выделение в куче с new/delete
- Время жизни объектов
- Распространённые ошибки работы с памятью