Я - новичок к C++ и направлению с проблемой.
Я читал в книге, что память выделена статической переменной, когда-то объект создается из того класса. Теперь, что, если я делаю эту статическую переменную глобальной? Когда это было бы инициализировано в этом случае?
Плюс, я также читал в некоторых статьях, что статические переменные выделены на "куче", и они не полагаются на конструкцию объектов... это верное? Если да, объясните, что инициализация памяти ступает в меня, я нуждаюсь в помощи.
Большое спасибо!
Во-первых: ПРЕКРАТИТЕ ДУМАТЬ О ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ В C И C ++, иначе вы сохраните состояние замешательства. Проблема более сложная, чем, например, в Python или Pascal, и поэтому вы не можете просто использовать одно слово для обозначения концепции (концепций).
Во-вторых, здесь нет «кучи» или «стека» - это детали операционной системы и процессора и не имеют ничего общего с абстрактной спецификацией языка C ++.
Теперь переменные имеют 1) область видимости, 2) связь и 3) класс хранения. Ключевое слово static используется для воздействия на все три аспекта, в зависимости от того, где вы его используете.
Область действия : где объявлена переменная. Если внутри функции, это область видимости функции, если вне функции, это область действия файла (что вы, вероятно, называете «глобальной переменной»).
Связь : доступна ли переменная из других единиц компиляции (актуально, если ваша программа состоит из нескольких исходных файлов).
Класс хранения :
Статические переменные выделяются в зависимости от реализации при запуске программы, и они действуют до завершения программы. Их нельзя «освободить» или «перераспределить». (типичная реализация - это сегменты 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, который будет выделен для каждой записи функции и освобожден для каждой функции. exit, а значит, и его значение уничтожено). Обратите внимание, что использование статических переменных в функциях очень несовместимо с многопоточностью и повторным входом, если вы не очень хорошо знаете, что делаете.
Статические переменные вообще не хранятся в куче.
Неинициализированные статические переменные хранятся в сегменте BSS.
Инициализированная статическая переменная хранится в сегменте данных.
Вы можете прочитать эту статью, в которой все это прекрасно объясняется: http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory
При запуске программы (до main) будет выделена память для вашей статической глобальной переменной.
У меня нет идей по второму вопросу.