Глобальные переменные, статические члены данных и статика на уровне функций не принадлежат ни стеку, ни куче; также называется «статическая продолжительность хранения».

смущает распределение памяти в C ++ с точки зрения областей памяти, таких как область данных Const, Stack, Heap, Freestore, Heap и Global / Static. Я хотел бы понять схему распределения памяти в следующем фрагменте. Может ли кто-нибудь помочь мне понять это. Если есть что-то еще, кроме типов переменных, упомянутых в примере, чтобы помочь лучше понять концепцию, измените пример.

class FooBar
{
      int n; //Stored in stack?

      public:

          int pubVar; //stored in stack?

          void foo(int param)  //param stored in stack
          {
                int *pp = new int; //int is allocated on heap.
                n = param;
                static int nStat;  //Stored in static area of memory
                int nLoc;          //stored in stack?
                string str = "mystring"; //stored in stack?
                ..
                if(CONDITION)
                {
                    static int nSIf; //stored in static area of memory
                    int loopvar;     //stored in stack
                    ..
                }
          }
}

int main(int)
{
     Foobar bar;    //bar stored in stack? or a part of it?

     Foobar *pBar;  //pBar is stored in stack

     pBar = new Foobar();  //the object is created in heap?  What part of the object is stored on heap

}

РЕДАКТИРОВАТЬ:
Что смущает меня, еслиpBar = new Foobar(); хранит объект в куче, как получаетсяint nLoc; а такжеint pubVar;компоненты компонента хранятся в стеке? Звучит противоречиво для меня. Не должен жизньpubvar а такжеpBar быть таким же?

 MSalters14 янв. 2011 г., 09:47
Подождите минуту. Стек является Java-конструкцией ?! Точно нет. Это конструкция С, если не старше. Ноsetjmp/longjmp очень ясно дал понять, что C имеет стек. Java, с другой стороны, позволяет объектам выходить за рамки функций, поэтому концепция стека там не существует (в отношении памяти; исключения - это другой вопрос)
 Martin York14 янв. 2011 г., 08:11
Лучшая идея - перестать думать о куче и стеке. Они на самом деле не существуют в C ++ (это конструкция Java / C #). Подумайте о продолжительности жизни (продолжительности) объекта.

Ответы на вопрос(4)

что считаю более правильным. Обратите внимание, что Томалак прав, что «стек» и «куча» не определены стандартом, и механизмы, отличные от стека, могут использоваться для передачи параметров для хранения автоматических переменных.

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

class Foobar
{
      int n; //Stored wherever the current object is stored
             //  (might be static memory, stack or heap depending 
             //  on how the object is allocated)

      public:

          int pubVar; //Stored wherever the current object is stored 
                      //  (might be static memory, stack or heap depending 
                      //  on how the object is allocated)

          void foo(int param)  //param stored in stack or register
          {
                int *pp = new int; //int is allocated on heap.
                n = param;
                static int nStat;  //Stored in static area of memory
                int nLoc;          //stored in stack or register
                string str = "mystring"; // `str` is stored in stack, however 
                                         //    the string object may also use heap 
                                         //    to manage its data
                ..
                if(CONDITION)
                {
                    static int nSIf; //stored in static area of memory
                    int loopvar;     //stored in stack or register
                    ..
                }
          }
}

int main(int)
{
     Foobar bar;    //bar stored in stack

     Foobar *pBar;  //pBar is stored in stack

     pBar = new Foobar();  //the object is created in heap.  
                           //   The non-static data members are stored in that
                           //   memory block.

}
 templatetypedef14 янв. 2011 г., 03:14
+1 Отличное, подробное, методическое объяснение.
 Michael Burr14 янв. 2011 г., 03:24
@ Махатма: да, это то, что я имею в виду.
 blitzkriegz14 янв. 2011 г., 03:19
@Micheal «в зависимости от того, как распределяется объект» мне не понятен. Вы имеете в виду следующее различие: Foobar bar; (// здесь объект располагается в стеке) Foobar * pBar = new Foobar (); (// здесь объект размещается в куче)
 Lightness Races in Orbit14 янв. 2011 г., 03:13
К сожалению, они неоднозначны и запутаны. Вполне возможно, что «большинство людей» используют их таким образом, но вряд ли это аргумент, чтобы избежать двусмысленности. «Большинство людей» думают, что Сидней является столицей Австралии; это никоим образом не делает это правильно.
 conio14 янв. 2011 г., 03:31
Хотя это практически невозможно для памяти, выделенной с использованием механизма свободного хранения (т.е.new), чтобы быть в стеке, я совсем не уверен, что автоматические переменные будутимеют быть найденным в стеке или в реестре. Я предполагаю, что реализация свободна положить кучу точно так же.Почему хотел бы он сделать такую вещь, это совершенно новый вопрос, хотя ...
Решение Вопроса

неточными и запутанными терминами, касающимися срока хранения.

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

Объекты с «динамической длительностью хранения» - это те, которые вы создаете набесплатный магазин с помощью ключевого словаnew (или, если ты глупый,malloc), а затем уничтожить в любое время с ключевым словомdelete (или, если ты глупый,free).

Существуют также объекты со «статической длительностью хранения», на которые распространяются всевозможные причудливые правила порядка инициализации и тому подобное. Мы склонны не использовать их в идиоматическом C ++ настолько, насколько мы можем этому помочь.

Что касается конкретных переменных в вашем примере кода, все ваши комментарии точны, несмотря на ошибку в терминологии.

Приложение:

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

В наши дни это не всегда так, и это определенно не предусмотрено стандартом C ++, который не заботится о том, где что-то хранится. Его волнует только то, как они созданы и уничтожены, и как долго они живут.

 Ariel14 янв. 2011 г., 03:09
Я думаю, что n и pubVar хранятся в куче, как часть объекта контейнера.
 Ariel14 янв. 2011 г., 03:12
Кстати - Томалак, хотя ваши комментарии в основном точны, нехорошо относиться к людям как к глупым или что-то в этом роде. Похоже, вы на пьедестале мудрых людей, а мы, мирские арканы, прообразы разумной жизни, созерцаем ваше величество. Пожалуйста, сохраните эти слова от тех, кто этого заслуживает, а не от тех, кто ошибочно называет «объекты стека» теми, которые хранятся в стеке точно ☺
 Lightness Races in Orbit14 янв. 2011 г., 03:06
На самом деле, обратите внимание, что члены класса с автоматической продолжительностью могут не находиться в физическом «стеке» (если такая вещь вообще существует), если инкапсулирующий класс был размещен в «куче» (если такая вещь даже существует). Еще один хороший пример того, почему вы не должны использовать эти термины.
 Lightness Races in Orbit14 янв. 2011 г., 05:10
@Mahatma: Помимо того факта, что вы, очевидно, полностью проигнорировали все, что я сказал о термине «куча», на самом деле нет. Указательpp не является членом классаFoobar; это просто локальная переменная функции. Несмотря на внешний вид, функции-члены на самом деле не «внутри» класса; конечно не с точки зрения хранения. «Откат» слова «куча» применяется только к фактическим переменным-членам.
 Dawson14 янв. 2011 г., 05:57
Разве это огорчает, что люди используют «стек» и «кучу»? Со временем слова могут обрести смысл за пределами того, что они буквально представляют. Люди связывают их как таковые, и очень снисходительно просто маркировать их как обманутых. Бесчисленные слова в английском языке приняли значения, полностью удаленные от их происхождения.

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

struct A {
  int n;  // you cannot say n is always on the stack, or always on the heap, etc.
};

int main() {
  A a;  // a is on the stack, so a.n is also on the stack
  A *p = new A();  // *p, which means the object pointed to by p, is on the heap,
                   // so p->n is also on the heap
                   // p itself is on the stack, just like a
  return 0;
}

A global;  // global is neither on the stack nor on the heap, so neither is global.n

«Стек» - это место, где находятся переменные, ограниченные временем жизни одного вызова функции; это также называется «длительностью автоматического хранения». Существуют различные стратегии выделения стеков, и, в частности, каждый поток имеет свой собственный стек, хотя тот, который является «стеком», должен быть понятен из контекста. Есть интересные вещи, происходящие с разделенными стеками (которые позволяют расти и уменьшаться), но в этом случае это все еще один стек, разбитый на несколько частей.

«Куча» является лишь неправильным в том смысле, что «к» относится к «основной» куче, используемой malloc и различными формами new; это также называется «динамическая продолжительность хранения».

Глобальные переменные, статические члены данных и статика на уровне функций не принадлежат ни стеку, ни куче; также называется «статическая продолжительность хранения».

C ++ не волнует, где хранятся вещи. Его волнует только то, как они построены и разрушены, и как долго они живут.

Как это происходит, определяется реализацией, компилятор может оптимизировать таким образом, что у вас ничего не будет храниться в «стеке», когда вы этого ожидаете. Способ распределения в куче определяется реализацией функции new / malloc или какой-либо сторонней функции (new может вызывать malloc).

Что, скорее всего, произойдет в вашем примере, это:

Foobar bar; // bar will *most likely* be allocated on the "stack".
Foobar *pBar; // pBar will *most likely* be allocated on the "stack".
pBar = new Foobar(); // pBar will stay as is, and point to the location on the "heap" where your memory is allocated by new.  

Несколько вещей, которые могут вас удивить. Массив в стиле C, напримерint array[5] не хранится так же, какint* pointer= new int[5]во втором случае, скорее всего, будет использоваться больше памяти, поскольку он хранит не только память для массива, но и память в «стеке» для указателя.

Статические константы, такие как5 а также"cake" обычно хранятся в отдельном разделе .DATA исполняемого файла.

При использовании C ++ важно понимать, что большинство этих вещей определяется реализацией.

 Lightness Races in Orbit14 янв. 2011 г., 03:23
+1 за то, что в основном прав.
 blitzkriegz14 янв. 2011 г., 03:23
Так как вы говоритенаверняка, может выделение / * Foobar бар; * / случается в куче?
 Lightness Races in Orbit14 янв. 2011 г., 05:04
@ Майкл, я думаю, что они не используют кучу.
 Lightness Races in Orbit14 янв. 2011 г., 03:24
@ Махатма: Абсолютно. Зависит от того, где вы пишете это! КСТАТИ на SO backticks может разделить примеры кода и отформатировать их для вас.
 Lightness Races in Orbit14 янв. 2011 г., 03:48
@Mahatma:struct Foobar {}; struct Foo { Foobar bar; }; int main() { Foo* x = new Foo(); delete x; } -- единственныйFoobar в этой программе находится в бесплатном магазине, или "куча", как вы выразились .... хотя в контекстеFooон имеет автоматическую продолжительность хранения (именно поэтому ваш инстинкт неправильно сообщает вам, что он находится в воображаемом «стеке»).

Ваш ответ на вопрос