Где статические переменные хранятся в C и C++?

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

169
задан Ciro Santilli 新疆改造中心法轮功六四事件 8 September 2018 в 22:30
поделиться

10 ответов

То, куда Ваши помехи идут, зависит от того, если они инициализированы нулем или нет. инициализированный нулем статические данные входят .BSS (Блок, Запущенный Символом) , не инициализированный нулем , данные входят .DATA

124
ответ дан tilz0R 23 November 2019 в 20:51
поделиться

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

0
ответ дан Robert Gould 23 November 2019 в 20:51
поделиться

Ответ мог бы очень хорошо зависеть от компилятора, таким образом, Вы, вероятно, хотите отредактировать свой вопрос (я имею в виду, даже понятие сегментов не получает мандат ISO C, ни C++ ISO). Например, в Windows исполняемый файл не носит имена символа. Одно 'нечто' было бы смещено 0x100, другой, возможно, 0x2B0, и код от обеих единиц перевода компилируется, зная смещения для "их" нечто.

1
ответ дан MSalters 23 November 2019 в 20:51
поделиться

Данные, объявленные в единице компиляции, войдут в.BSS или.Data того вывода файлов. Инициализируемые данные в BSS, uninitalised в ДАННЫХ.

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

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

5
ответ дан itj 23 November 2019 в 20:51
поделиться

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

2
ответ дан Ilya 23 November 2019 в 20:51
поделиться

в "глобальной и статической" области:)

существует несколько областей памяти в C++

  • "куча"
  • свободное хранилище
  • стек
  • глобальный & статичный
  • константа

см. здесь для подробного ответа на Ваш вопрос

10
ответ дан ugasoft 23 November 2019 в 20:51
поделиться

Я не полагаю, что будет коллизия. Используя статический на уровне файла (вне функций) отмечает переменную как локальную для текущей единицы компиляции (файл). Это никогда не видимо вне текущего файла, поэтому никогда не должен иметь имя.

Используя статический в функции отличается - переменная только видима к функции, это - просто свое значение, сохраняется через вызовы к той функции.

В действительности, статичный делает две разных вещи в зависимости от того, где это. В oth случаях однако, это ограничивает видимость переменной для предотвращения столкновений пространства имен,

Однако я полагаю, что это было бы сохранено в ДАННЫХ, которые имеют тенденцию инициализировать переменную. BSS первоначально выдержан за byte-set-< что-то>, который содержал переменные, которые не были инициализированы.

13
ответ дан paxdiablo 23 November 2019 в 20:51
поделиться

Место хранения данных будет зависящим от реализации.

Однако значение статичный является "внутренней связью". Таким образом символ внутренний к единице компиляции (foo.c, bar.c) и не может быть сослан вне той единицы компиляции. Так, не может быть никаких коллизий имени.

21
ответ дан Seb Rose 23 November 2019 в 20:51
поделиться

На самом деле переменная является кортежем (устройство хранения данных, объем, введите, обратитесь, значение):

storage     :   where is it stored, for example data, stack, heap...
scope       :   who can see us, for example global, local...
type        :   what is our type, for example int, int*...
address     :   where are we located
value       :   what is our value

Локальный объем мог означать локальный или для переводной единицы (исходный файл), функция или для блока в зависимости от где его определенный. Для создания переменной видимой больше чем к одной функции это определенно должно быть или в ДАННЫХ или в области BSS (в зависимости от ли его инициализированный явно или нет, соответственно). Его тогда ограниченный по объему соответственно или ко всей функции (функциям) или к функции (функциям) в исходном файле.

32
ответ дан yogeesh 23 November 2019 в 20:51
поделиться

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

6
ответ дан trotterdylan 23 November 2019 в 20:51
поделиться