Выделение памяти (C ++) Время компиляции / время выполнения? - PullRequest
1 голос
/ 10 сентября 2011

Я не уверен, насколько уместен этот вопрос, но -

Мне любопытно, как компилятор выделяет память для объекта (распределение памяти) еще до того, как он будет построен (до того, как даже будет вызван конструктор!) .

Как это происходит с примитивными типами данных?

Звучит немного наивно, но что именно?

Является ли это полностью процессом во время выполнения или у него (у компилятора) есть какие-либо планы, такие как , чтобы сделать это , , чтобы сделать это , во время выполнения, которое он решает перед рукой во время компиляции . Понятия не имею!

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

Другими словами, когда происходит выделение памяти для буквально ЛЮБОГО вида переменных, с точки зрения времени, в какой момент? На каком этапе компиляции (или выполнения)?

Ответы [ 3 ]

7 голосов
/ 10 сентября 2011

Распределение памяти всегда происходит во время выполнения.Резервирование памяти для объектов, находящихся в стеке или для статических переменных, происходит во время компиляции (или во время выполнения для VLA C99).

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

2 голосов
/ 10 сентября 2011

Существует (в широком смысле) три типичных сценария: распределение в стеке, выделение из кучи и статическое выделение.

Первое, что происходит, когда вы объявляете локальную переменную внутри функции:

void foo ( )
{
   int bar = 42;
}

Здесь память для bar выделяется в стеке . Он выделяется во время foo вызова.

Второй сценарий происходит при создании экземпляра класса с оператором new:

void foo ( )
{
    MyClass* bar = new MyClass( );
}

Здесь память для i выделяется в куче . Это снова происходит во время выполнения и происходит при выполнении оператора new. Он работает в основном так же, как C malloc, если вы более знакомы с этим.

Наконец, есть статическое распределение.

void foo ( )
{
    static int bar = 42;
}

Здесь компилятор заранее знает, что для bar потребуется память, и поэтому он вставляет в исполняемый файл инструкцию, указывающую исполняющему загрузчику зарезервировать пространство, или буквально освобождает место в исполняемом файле для переменной, чтобы постоянно находится в памяти. Поэтому память для bar обычно выделяется во время выполнения, так как исполняемый файл загружается.

2 голосов
/ 10 сентября 2011

Распределение объектов, созданных с помощью new или new[] или другого варианта, выполняется во время выполнения путем доступа к свободному хранилищу и поиска достаточного пространства для размещения нового объекта до запуска конструктора.

Выделение для локальных объектов внутри функции выполняется во время выполнения.Однако обычно это достигается путем перемещения указателя стека на правильный размер байтов, и пространство между предыдущим значением и новым значением теперь зарезервировано для объекта.Конструкторы запускаются после запуска пространства.

Распределение для глобальных и статических объектов выполняется компилятором во время компиляции, а их конструкторы запускаются при загрузке модуля преобразования, в котором они определены (обычно перед основной() начинает выполняться).

Распределение объектов, содержащихся непосредственно (не через указатель) в другом объекте, выполняется как часть выделения для этого объекта.

...