Динамическое выделение памяти
В C++ существует два основных способа выделения памяти:
-
Статическое выделение - память выделяется во время компиляции (стек)
-
Динамическое выделение - память выделяется во время выполнения программы (куча)
Динамическая память управляется операторами new и delete.
Оператор new
Оператор new выделяет память в куче и возвращает указатель на выделенную область.
Оператор delete
Оператор delete освобождает память, выделенную оператором new.
Опасности динамической памяти
-
Утечки памяти - если не освободить память с помощью
deleteint *ptr = new int; // Забыли вызвать delete ptr - утечка памяти! -
Двойное удаление
int *ptr = new int; delete ptr; delete ptr; // Ошибка! Попытка удалить уже освобожденную память -
Висячие указатели
int *ptr = new int; int *ptr2 = ptr; delete ptr; *ptr2 = 10; // Опасное поведение! ptr2 теперь висячий указатель
Умные указатели
В современном C++ рекомендуется использовать умные указатели вместо raw pointers:
-
std::unique_ptr- эксклюзивное владение -
std::shared_ptr- разделяемое владение -
std::weak_ptr- слабая ссылка
Примеры
Динамический массив
Пояснение: Пользователь вводит размер массива, который выделяется в куче. После использования память освобождается.
Двумерный динамический массив
Пояснение: Создается двумерный массив, где сначала выделяется массив указателей, а затем для каждого указателя выделяется массив значений. Освобождение происходит в обратном порядке.
Рекомендации по работе с динамической памятью
-
Всегда проверяйте, что
newвернул не-nullptr (в старых стандартах) -
Используйте
deleteдля одиночных объектов иdelete[]для массивов -
После
deleteустанавливайте указатель вnullptr -
По возможности используйте умные указатели вместо raw pointers
-
Избегайте "голого"
newиdeleteв высокоуровневом коде
Динамическое выделение памяти дает гибкость, но требует осторожности. Всегда следите за освобождением памяти и предпочитайте современные методы управления ресурсами.