Динамическое выделение памяти
В C++ существует два основных способа выделения памяти:
-
Статическое выделение - память выделяется во время компиляции (стек)
-
Динамическое выделение - память выделяется во время выполнения программы (куча)
Динамическая память управляется операторами new
и delete
.
Оператор new
Оператор new
выделяет память в куче и возвращает указатель на выделенную область.
Оператор delete
Оператор delete
освобождает память, выделенную оператором new
.
Опасности динамической памяти
-
Утечки памяти - если не освободить память с помощью
delete
int *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
в высокоуровневом коде
Динамическое выделение памяти дает гибкость, но требует осторожности. Всегда следите за освобождением памяти и предпочитайте современные методы управления ресурсами.