Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Различия между heap и stack в C++
Stack и heap — два способа управления памятью в C++, с кардинально разными характеристиками. Это базовое знание, критичное для написания эффективного кода.
Stack (Стек)
Как работает:
void function() {
int x = 5; // Stack: адрес = рег+смещение
double y = 3.14; // Stack
char arr[100]; // Stack: 100 байт подряд
}
// x, y, arr автоматически удаляются
Характеристики stack:
- Быстро: присваивание памяти = просто сдвинуть указатель stack pointer
- Ограничен: обычно 1-8 МБ на поток
- LIFO: Last In - First Out (как настоящий стек)
- Автоматическое управление: RAII - выход из scope = деструкция
- Локальная видимость: переменные видны только внутри scope
Когда stack переполняется:
void bad() {
char huge_buffer[1000000]; // 1 МБ на stack
// ... обычно это вызывает stack overflow
}
void recursive(int n) {
if (n == 0) return;
int data[100];
recursive(n - 1); // Каждый вызов добавляет 400 байт на stack
}
Heap (Куча)
Как работает:
void function() {
int* ptr = new int(5); // Heap: динамическое выделение
double* arr = new double[100]; // Heap: массив на куче
// ... работаем с данными ...
delete ptr; // Ручное освобождение!
delete[] arr; // delete[] для массивов!
}
Характеристики heap:
- Медленнее: требует поиска подходящего блока, фрагментация
- Большой: может быть гигабайты
- Ручное управление: ты отвечаешь за new/delete
- Глобальная видимость: через указатели можно работать отовсюду
- Долгоживущие данные: остаётся до явного delete
Утечки памяти:
// УТЕЧКА!
void leak() {
int* ptr = new int(42);
return; // Забыли delete!
}
// Утечка в исключении
void leak_exception() {
int* ptr = new int(42);
do_something(); // Если выбросит исключение - утечка!
delete ptr;
}
Smart Pointers - безопасная альтернатива
#include <memory>
// unique_ptr - единственный владелец
std::unique_ptr<int> ptr1(new int(42));
// или
auto ptr2 = std::make_unique<int>(42);
// ptr1 удалится автоматически при выходе из scope
// shared_ptr - коллективное владение
std::shared_ptr<int> ptr3 = std::make_shared<int>(42);
std::shared_ptr<int> ptr4 = ptr3; // Счётчик ссылок = 2
// Удалится, когда счётчик = 0
Сравнительная таблица
| Характеристика | Stack | Heap |
|---|---|---|
| Скорость | Очень быстро | Медленнее |
| Размер | 1-8 МБ | Гигабайты |
| Управление | Автоматическое | Ручное (или smart) |
| Время жизни | До конца scope | До delete |
| Фрагментация | Нет | Да |
| Потокобезопасность | Да (разные потоки разные stack) | Нет (требует синхронизации) |
Практический пример
#include <vector>
#include <memory>
class Data {
public:
int values[1000]; // 4000 байт
};
void good() {
// Большие объекты - на heap
std::unique_ptr<Data> data = std::make_unique<Data>();
// Контейнеры берут память из heap автоматически
std::vector<int> vec; // Сам вектор на stack, данные на heap
vec.push_back(42);
} // Автоматический cleanup
void bad() {
// Не делай так!
Data stack_data; // Пытаемся положить 4000 байт на stack
int* heap_data = new int;
// ... забыли delete
}
Правило: когда что использовать
Используй stack для:
- Локальных переменных малого размера (< 1 КБ)
- Которые видны только в одном scope
- Временных данных
Используй heap для:
- Больших объектов (> 10 КБ)
- Данных, жизненный цикл которых неизвестен
- Контейнеров: vector, map, string (сам контейнер на stack, данные на heap)
Используй smart pointers для:
- Любого динамического выделения (вместо new/delete)
- unique_ptr если один владелец
- shared_ptr если несколько владельцев