Указатели и память

Управление динамической памятью

Динамическая память нужна, когда размер или lifetime неизвестны при компиляции.

Что такое Управление динамической памятью?

Динамическая память нужна, когда размер или lifetime неизвестны при компиляции.

Выделите массив во время выполнения и безопасно освободите его.

Важные моменты

  • Указатель ссылается на живой совместимый объект или равен null.
  • Каждое собственное выделение освобождается ровно один раз.
  • Явно выражайте ownership и const.

Примеры кода на C и C++

C
Запустить →
main.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
C++
Запустить →
main.cpp
#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 сочетает malloc/calloc с free и проверяет ошибки; std::vector автоматически владеет и освобождает память даже при exceptions.

C

Ownership и очистка — соглашения, контролируемые программистом.

C++

Контейнеры и RAII связывают ownership и очистку с lifetime объекта.

Практические задания

Запустите обе версии и изменяйте их, сравнивая гарантии языков.

  • Проверьте null и отказ выделения памяти.
  • Используйте AddressSanitizer и UndefinedBehaviorSanitizer.
  • Документируйте ownership каждого указателя.