Управление динамической памятью в C и C++
В этом уроке вы выделите память под массив, размер которого известен только во время работы программы, и безопасно освободите её.
Введение
Динамическая память нужна, когда размер или время жизни данных нельзя определить при компиляции, например когда число элементов зависит от ввода пользователя. Такая память выделяется во время работы программы, и её нужно освободить, когда она больше не нужна.
Главное
- Указатель должен указывать только на существующий объект нужного типа или быть равен null.
- Каждую выделенную область памяти нужно освободить ровно один раз.
- Явно обозначайте, какая функция владеет памятью (ownership), а какие данные только читаются (const).
Примеры кода на C и C++
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t count = 5;
int *values = calloc(count, sizeof *values);
if (!values) return 1;
for (size_t i = 0; i < count; ++i) values[i] = (int)(i * i);
printf("last=%d\n", values[count - 1]);
free(values);
return 0;
}
last=16
#include <iostream>
#include <vector>
int main() {
std::vector<int> values(5);
for (std::size_t i = 0; i < values.size(); ++i) values[i] = static_cast<int>(i * i);
std::cout << "last=" << values.back() << '\n';
}
last=16
Сравнение C и C++
В C calloc выделяет память под 5 целых чисел и заполняет их нулями. Программа должна проверить, не произошла ли ошибка выделения, и в конце вызвать free, иначе будет утечка памяти (memory leak). В C++ std::vector сам управляет памятью и автоматически освобождает её, когда перестаёт использоваться, даже если возникло исключение.
Владение памятью и её освобождение полностью лежат на программисте.
Контейнеры и RAII автоматически освобождают ресурсы, когда заканчивается время жизни объекта.
Упражнения для практики
Запустите обе версии, а затем измените код, чтобы увидеть разницу в безопасности, которую даёт каждый язык.
- Проверьте работу с нулевыми указателями и при ошибках выделения памяти.
- Запустите программу с AddressSanitizer и UndefinedBehaviorSanitizer, чтобы найти ошибки работы с памятью.
- Явно обозначьте, какой указатель владеет памятью, а какой служит только для чтения.
Попрактикуйтесь на задаче
Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.
Все задачи