← Назад к вопросам

Есть ли в C++ сборщик мусора (garbage collector)?

1.6 Junior🔥 131 комментариев
#Структуры данных и алгоритмы#Умные указатели и управление памятью#Язык C++

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Есть ли в C++ сборщик мусора

Коротко: Нет, в стандартном C++ нет встроенного сборщика мусора. Управление памятью — ответственность программиста.

Почему нет сборщика мусора в C++

1. Философия C++

C++ следует принципу: "Не платишь за то, что не используешь" (Zero-Cost Abstraction). Сборщик мусора требует:

  • Постоянный overhead на отслеживание ссылок
  • Pauses для сборки (Stop-the-World)
  • Дополнительное использование памяти

Это неприемлемо для системного программирования.

2. Контроль производительности

// Явное управление даёт полный контроль
int* ptr = new int[1000000];
// Используем...
delete[] ptr;  // Освобождаем точно когда нужно

// С GC:
// - Когда освободится память? Неизвестно
// - Может возникнуть GC pause в критический момент
// - Непредсказуемо для real-time систем

3. Системное программирование

// Ядро ОС, драйверы, embedded системы
// требуют точного контроля над памятью
char buffer[PAGE_SIZE];
// Нельзя полагаться на GC

Как управлять памятью в C++

1. Умные указатели (Smart Pointers) - РЕКОМЕНДУЕТСЯ

#include <memory>

int main() {
    // unique_ptr — уникальное владение
    std::unique_ptr<int> p1(new int(42));
    // или
    auto p2 = std::make_unique<int>(42);
    // Автоматически удалится когда выйдет из scope
    
    // shared_ptr — совместное владение
    std::shared_ptr<int> p3 = std::make_shared<int>(10);
    std::shared_ptr<int> p4 = p3;  // Оба владеют
    // Удалится когда последний shared_ptr уничтожится
    
    return 0;
}  // Автоматическая очистка

2. RAII (Resource Acquisition Is Initialization)

class FileHandler {
private:
    std::ofstream file;
public:
    FileHandler(const std::string& name) {
        file.open(name);
    }
    ~FileHandler() {
        file.close();  // Автоматически!
    }
};

int main() {
    {
        FileHandler fh("data.txt");
        fh.write("hello");
    }  // Деструктор вызовется автоматически
    
    return 0;
}

3. Стековая память (Stack Memory)

int main() {
    // На стеке — автоматически очищается
    int x = 42;              // Удалится при выходе
    std::string s = "hello"; // Удалится при выходе
    std::vector<int> v{1,2,3}; // Удалится при выходе
    
    // На куче — нужно управлять
    int* p = new int(42);
    delete p;  // Нужно явно
    
    return 0;
}

Проблемы при ручном управлении

Утечка памяти (Memory Leak)

// НЕПРАВИЛЬНО — утечка
int* p = new int(42);
if (someError) return;  // Утечка!

// ПРАВИЛЬНО — с умным указателем
auto p = std::make_unique<int>(42);
if (someError) return;  // Освободится автоматически

Double Delete

// НЕПРАВИЛЬНО
int* p = new int(42);
delete p;
delete p;  // CRASH! Undefined behavior

// ПРАВИЛЬНО
auto p = std::make_unique<int>(42);
// Даже если скопировать нельзя

Опции при наличии сборщика мусора

В некоторых случаях C++ может использовать расширения:

Boehm GC (Для экспериментов)

#include <gc.h>

int main() {
    GC_INIT();
    
    int* p = (int*)GC_malloc(sizeof(int));
    *p = 42;
    // Память будет освобождена автоматически
    
    return 0;
}

Но это не рекомендуется для production!

Мониторинг утечек

Valgrind (Linux)

g++ -g program.cpp -o program
valgrind --leak-check=full ./program

AddressSanitizer

g++ -fsanitize=address -g program.cpp
./a.out

Сравнение с другими языками

ЯзыкGCКонтроль
C++НетПолный
JavaДаСредний
C#ДаСредний
GoДаОграниченный
RustНетПолный (через borrow checker)
PythonДаОграниченный

Лучшие практики

  1. Используй умные указатели
auto ptr = std::make_unique<MyClass>();  // Не new!
  1. Избегай raw new/delete
// НЕПРАВИЛЬНО
MyClass* obj = new MyClass();
delete obj;

// ПРАВИЛЬНО
auto obj = std::make_unique<MyClass>();
  1. Используй стековую память где возможно
std::vector<int> v;  // Стек, автоматическое расширение
  1. RAII для всех ресурсов
class Database {
    ~Database() { connection.close(); }  // Автоматическое закрытие
};

Резюме

  • Нет встроенного GC — C++ требует явного управления
  • Умные указатели (unique_ptr, shared_ptr) — почти как GC
  • RAII паттерн — автоматическое управление ресурсами
  • Стековая память — для простых данных
  • Контроль производительности — основная причина отсутствия GC
  • Инструменты для поиска утечек: Valgrind, AddressSanitizer
Есть ли в C++ сборщик мусора (garbage collector)? | PrepBro