Управление памятью в C++: экспертное использование new и delete
Управление памятью в C++: экспертное использование new и delete
Это руководство объясняет, как выделять и освобождать память в куче с помощью new и delete, на чётких реальных примерах.
C++ даёт разработчикам возможность выделять память во время выполнения — это называется динамическим выделением памяти. В отличие от управляемых языков (Java, Python), C++ не освобождает память в куче автоматически; программист должен делать это явно.
Операторы new и delete — базовый механизм для этой задачи. Они являются краеугольным камнем ручного управления памятью в C++ и определены в стандартной библиотеке C++.
Оператор new
Оператор new выделяет блок памяти в куче и возвращает указатель на его первый байт. Например:
// Объявление указателя на int
int* pointVar;
// Динамическое выделение памяти через new
pointVar = new int;
// Присвоение значения выделенной памяти
*pointVar = 45;
В этом фрагменте pointVar получает адрес нового int. Поскольку new возвращает указатель, переменная должна быть указателем. Для массивов new возвращает указатель на первый элемент:
int* arr = new int[10]; // arr указывает на первый элемент массива из 10 int
Общий синтаксис:
pointerVariable = new dataType; // одиночный объект
pointerVariable = new dataType[size]; // массив
Оператор delete
Когда объект или массив, выделенный через new, больше не нужен, нужно вызвать delete, чтобы вернуть память операционной системе. Несоблюдение этого правила приводит к утечкам памяти, снижающим производительность или вызывающим сбои.
Для одиночного объекта:
delete pointerVariable;
Для массива, выделенного через new[], используйте массивную форму:
delete[] pointerVariable;
Пример полного жизненного цикла:
// Выделение int
int* pointVar = new int;
*pointVar = 45;
cout << *pointVar; // Вывод: 45
// Освобождение
delete pointVar;
new должен соответствовать delete (или delete[] для массивов). В продакшн-коде используйте RAII или умные указатели (std::unique_ptr, std::shared_ptr) для автоматизации.Пример 1: Базовое динамическое выделение
#include <iostream>
using namespace std;
int main() {
int* pointInt;
float* pointFloat;
pointInt = new int;
pointFloat = new float;
*pointInt = 45;
*pointFloat = 45.45f;
cout << *pointInt << endl;
cout << *pointFloat << endl;
delete pointInt;
delete pointFloat;
return 0;
}
Вывод
45 45.45
Программа демонстрирует выделение двух примитивных типов, присваивание, вывод и корректное освобождение.
Пример 2: Выделение массива float
#include <iostream>
using namespace std;
int main() {
int num;
cout << "Enter total number of students: ";
cin >> num;
float* ptr = new float[num];
cout << "Enter GPA of students." << endl;
for (int i = 0; i < num; ++i) {
cout << "Student" << i + 1 << ": ";
cin >> *(ptr + i);
}
cout << "\nDisplaying GPA of students." << endl;
for (int i = 0; i < num; ++i) {
cout << "Student" << i + 1 << " :" << *(ptr + i) << endl;
}
delete[] ptr;
return 0;
}
Вывод
Enter total number of students: 4 Enter GPA of students. Student1: 3.6 Student2: 3.1 Student3: 3.9 Student4: 2.9 Displaying GPA of students. Student1 :3.6 Student2 :3.1 Student3 :3.9 Student4 :2.9
Программа запрашивает количество студентов, выделяет массив float соответствующего размера, собирает ввод, выводит данные и освобождает память через delete[].
Пример 3: Динамическое выделение объекта
#include <iostream>
using namespace std;
class Student {
int age;
public:
Student() : age(12) {}
void getAge() {
cout << "Age = " << age << endl;
}
};
int main() {
Student* ptr = new Student();
ptr->getAge();
delete ptr;
return 0;
}
Вывод
Age = 12
Создаётся объект Student в куче. Конструктор инициализирует age значением 12, метод getAge выводит его. После использования delete освобождает память объекта.
Современные альтернативы (C++11 и новее)
В современном C++ ручное управление памятью через new/delete заменяется на:
- std::unique_ptr — единственное владение, автоматическое удаление.
- std::shared_ptr — совместное владение с подсчётом ссылок.
- std::make_unique / std::make_shared — безопасное создание.
- std::vector, std::string — контейнеры, управляющие памятью сами.
Пример с unique_ptr:
#include <memory>
#include <iostream>
int main() {
auto ptr = std::make_unique<Student>();
ptr->getAge();
// delete не нужен — автоматическое удаление при выходе из области видимости
}
Язык C
- Основы цифровой памяти: адресация, доступ и волатильность
- Освоение переменных, литералов и констант в C++: подробное руководство
- Классы и объекты в C++: практическое руководство по объектно-ориентированному программированию
- Публичное, защищённое и приватное наследование в C++: подробный разбор
- Дружественные функции и классы в C++: мастерство контроля доступа
- Управление директориями и файлами в Python: полное руководство
- Структуры C++ против классов: практическое руководство для разработчиков встроенных систем
- Raspberry Pi 3 B+ — Обновленные характеристики, спецификации и руководство по покупке
- GE Digital представляет ПО для предиктивного управления активами, переводящее обслуживание из реактивного в проа…
- Wittmann Battenfeld представляет новую серию X и робот Primus 14