Когда память выделяется статическим переменным в C ++ - PullRequest
10 голосов
/ 17 июля 2010

Я новичок в C ++ и столкнулся с проблемой.

Я прочитал в книге, что память выделяется для статической переменной, как только объект создан из этого класса.А что если я сделаю эту статическую переменную глобальной?Когда это будет инициализировано в этом случае?

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

Большое спасибо!

Ответы [ 3 ]

29 голосов
/ 17 июля 2010

Первое: перестаньте думать о глобальных переменных в C и C ++, иначе вы увековечите свое замешательство.Проблема более сложная, чем, например, в Python или Pascal, и поэтому вы не можете просто использовать одно слово для понятия (ов).

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

Теперь переменные имеют 1) область действия, 2) связь и 3) класс хранения.Ключевое слово static используется для воздействия на все три аспекта, в зависимости от того, где вы его используете.

Область действия : где объявлена ​​переменная.Если внутри функции, это область действия функции, если за пределами функции это область действия файла (то, что вы, вероятно, называете «глобальной переменной»).

Linkage :доступна ли переменная из других модулей компиляции (актуально, когда ваша программа состоит из нескольких исходных файлов).

Класс хранения :

Статические переменныераспределяются в порядке, определяемом реализацией, при запуске программы и живут до завершения программы.Они не могут быть «освобождены» или «перераспределены».(типичной реализацией являются сегменты BSS и DATA, как уже упоминали другие).

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

Динамический класс хранения - это то, что вы, вероятно, называете «кучей».Это переменные, чье хранение напрямую управляется через malloc / free или new / delete.Хранилище для статических переменных управляется ОЧЕНЬ иначе, чем динамическое хранилище, и два вида хранилища принципиально несовместимы.

Пример:

===
// ALL file-scope variables have static storage class
int global1;        // file-scope, external linkage
static int global2; // file-scope, internal linkage

void f()
{
  static int x;     // static storage class, function-scope
  int y;            // automatic storage class, function-scope

  free(&x);         // ILLEGAL, WILL CRASH!
  free(&y);         // DITTO!
  free(&global1);   // DITTO!
}
===

Теперь все переменные со статическим классом хранилища(global1, global2 и x) выделяются и инициализируются перед запуском программы.Если вы не укажете начальные значения, они будут инициализированы по умолчанию в НЕУКАЗАННОМ ПОРЯДКЕ.(Для примитивных типов это просто означает заполнение нулями).

Статические переменные освобождаются только при выходе из программы.Это означает, что «x» в функции f будет инициализировано ТОЛЬКО ОДИН РАЗ (при запуске программы) и что он ОСТАВЛЯЕТ ЕГО ЗНАЧЕНИЕ между вызовами функции (в отличие от y, который будет выделен для каждой записи функции и освобожден для каждой функции).выход, таким образом, также его значение уничтожено).Обратите внимание, что использование статических переменных внутри функций очень несовместимо с многопоточностью и повторным входом, если вы очень хорошо знаете, что делаете.

9 голосов
/ 17 июля 2010

Статические переменные вообще не хранятся в куче.

Неинициализированные статические переменные хранятся в сегменте BSS.

Инициализированные статические переменные хранятся в сегменте данных.

Вы можете прочитать эту статью, которая объясняет все это в отличной форме: http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory

1 голос
/ 17 июля 2010

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

Понятия не имею по второму вопросу.

...