Вопрос

В контексте C++ (не то чтобы это имело значение):

class Foo{
    private:
        int x[100];
    public:
        Foo();
}

То, что я узнал, говорит мне, что если вы создадите экземпляр Foo следующим образом:

Foo bar = new Foo();

Затем массив x размещается в куче, но если вы создали экземпляр Foo следующим образом:

Foo bar;

Затем он создается в стеке.

Я не могу найти ресурсы в Интернете, чтобы подтвердить это.

Это было полезно?

Решение

Учитывая небольшую модификацию вашего примера:

class Foo{
    private:
        int x[100];
        int *y;
    public:
        Foo()
        {
           y = new int[100];
        }
        ~Foo()
        { 
           delete[] y; 
        }

}

Пример 1:

Foo *bar = new Foo();
  • x и y находятся в куче:
  • sizeof(Foo*) создается в стеке.
  • sizeof(int) * 100 * 2 + sizeof(int *) находится в куче

Пример 2:

Foo bar;
  • x находится в стеке, а y — в куче
  • sizeof(int) * 100 находится в стеке (x) + sizeof(int*)
  • sizeof(int) * 100 находится в куче (y)

Фактические размеры могут незначительно отличаться из-за выравнивания классов/структур в зависимости от вашего компилятора и платформы.

Другие советы

Строго говоря, согласно стандарту объект не обязательно должен существовать в стеке или куче.Стандарт определяет 3 типа «длительности хранения», но не определяет, как именно должно быть реализовано хранение:

  1. продолжительность статического хранения
  2. автоматическая продолжительность хранения
  3. продолжительность динамического хранения

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

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

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

В стандарте говорится следующее об этих вещах (ниже приведены выдержки из различных битов 3.7 - Продолжительность хранения):

Статические и автоматические продолжительность хранения связаны с объектами, введенными объявлениями (3.1) и неявно создаваемыми в реализации (12.2).Динамическая продолжительность хранения связана с объектами, созданными с новым оператором (5.3.4).

...

Все объекты, которые не имеют динамической продолжительности хранения и не являются локальными, имеют статическую продолжительность хранения.Хранение этих объектов должно длиться на протяжении всей программы (3.6.2, 3.6.3).

...

Локальные объекты явно объявлены Auto или Register или не явно объявленные статические или внешние, имеют автоматическую продолжительность хранения.Хранение этих объектов длится до блока, в котором они созданы выходы.

...

Объекты могут быть созданы динамически во время выполнения программы (1.9), с использованием новых экспрессией (5.3.4) и уничтожены с использованием удаления-экспрессии (5.3.5).Реализация AC + + обеспечивает доступ к динамическому хранилищу динамического хранилища через глобальные функции распределения.

...

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

И наконец (относительно массива в вашем примере):

3.7.4 Продолжительность подобъектов [basic.stc.inherit]

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

Объект типа Foo принимает размер 100 дюймов, хранящихся в последовательности. Если вы создадите его в стеке, вы получите все это в стеке. Если вы сделаете это с новым, он будет в куче как часть объекта.

Это часть языковой спецификации, я не уверен, какой у вас вопрос.

Да, массив элементов x будет создан в куче, если вы создадите объект Foo в куче. Когда вы выделяете динамическую память для Foo , вы запрашиваете память длиной sizeof (Foo) (плюс, возможно, некоторые накладные расходы памяти, но давайте пока проигнорируем это), что в вашем примере кода подразумевается размер 100 int s. Этот должен иметь дело с продолжительностью жизни объектов типа Foo (и их внутренних данных) для пересечения областей.

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

struct Foo {
    int* y;
    Foo() : y(new int()) { }
    ~Foo() { delete y; }
};

создаст y в куче независимо от того, был ли объект Foo создан в стеке или в куче.

Вы имеете в виду

Foo* bar = new Foo(); 

Я полагаю. Это создается в куче.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top