Как выделяется память под классы, выделяется ли она при определении класса?

Как выделяется память под классы, выделяется ли она при определении класса и при создании объекта класса?


Ответы (3 шт):

Автор решения: gbg

Так как C++ - сложный (очень) язык со множеством реализаций на разных архитектурах и агрессивной оптимизацией, рассмотрение всех нюансов оперирования с памятью растянется на длиннопост (который будет, фактически, плохим переводом львиной доли Стандарта).

Ниже я приведу самые примитивные примеры, которых достаточно для базового понимания ситуации. Оно годится для ответа в школе/вузе, но с ним может быть трудно на собеседовании, особенно если вам попадется language lawyer

При определении - нет (если совсем точно - это зависит от компилятора и его настроек). При объявлении экземпляра - есть три варианта.

Все дальнейшие примеры - это просто середина тела какой-то функции:

  1. Class clazz; - экземпляр создастся на стеке
  2. Class* clazz = new Class() - создастся на куче
  3. Class* clazz = new(ptr) Class() - создастся по адресу ptr - Placement New (куда показывает ptr - это уже забота программиста)

Также запись Class clazz; - может встретится как поле структуры/класса, но в таком случае память будет выделяться / удаляться в зависимости от жизни экземпляра структуры/класса.

→ Ссылка
Автор решения: Stanislav Volodarskiy

При компиляции определения класса создаются три вещи: код методов, VTBL если есть виртуальные методы, RTTI если его не отключили при компиляции. Вся эта информация попадает в исполнимый модуль и занимает место в памяти. Её объём во время работы программы не меняется.

Экземпляры класса тоже потребляют память. Каждый раз когда вы создаёте новый экземпляр вы обязаны предоставить ему память в которой он будет существовать.

→ Ссылка
Автор решения: user7860670

Выделение памяти можно разделить на две большие категории:

  1. Память распределяемая на этапе компиляции: объекты, содержимое которых известно на этапе компиляции (константы), машинный код функций, различная служебная информация, как то таблицы виртуальных методов, таблицы с информацией о типах, таблицы обработчиков исключений и т.п. Все это попадает в исполняемый файл и память под это все сразу выделяется системой при запуске приложения.

  2. Память, распределяемая на этапе выполнения программы: объекты, содержимое которых не известно на этапе компиляции. В этом случае выделение памяти может определяться:

    1. Компилятором - для всех объектов, имеющих время хранение automatic, static, thread local (то бишь созданных без оператора new).

    2. Программистом - для всех объектов, имеющих время хранения dynamic (то бишь созданных посредством оператора new). В этом случае опять возможны два варианта:

      1. Выделение памяти происходит с использованием глобальной или перегруженной функции выделения памяти (обычный синтаксис оператора new).

      2. Выделения памяти не происходит, объект размещается в указанном существующем буфере (синтаксис placement new).

→ Ссылка