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




9 Answers

Если ваша статика идет, зависит от того, были ли они инициализированы или нет. 0 инициализированных статических данных поступает в .BSS (Block Started by Symbol) , но не инициализированные данные идут в .DATA

В каком сегменте (.BSS, .DATA, other) исполняемого файла хранятся статические переменные, так что они не имеют конфликтов имен? Например:


foo.c:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

Если я скомпилирую оба файла и привяжу его к основному, который вызывает fooTest () и barTest несколько раз, операторы printf увеличиваются независимо. Имеет смысл, поскольку переменные foo и bar являются локальными для единицы перевода.

Но где выделено хранилище?

Чтобы быть ясным, предполагается, что у вас есть инструментальная цепочка, которая выводит файл в формате ELF. Таким образом, я считаю, что для этих статических переменных должно быть зарезервировано место в исполняемом файле.
В целях обсуждения предположим, что мы используем инструментальную цепочку GCC.




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

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

Локальная область может означать локальную или переводческую единицу (исходный файл), функцию или блок в зависимости от того, где она определена. Чтобы сделать переменную видимой для нескольких функций, она определенно должна находиться в области DATA или BSS (в зависимости от того, была ли она инициализирована явно или нет, соответственно). Затем он привязан к любой функции (ей) или функции (ей) в исходном файле.




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

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

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

Сказав это, я считаю, что он будет храниться в DATA, который, как правило, имеет инициализированную переменную. Первоначально BSS означала байтовый набор <something>, который содержал переменные, которые не были инициализированы.




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




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

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

  • куча
  • бесплатный магазин
  • стек
  • глобальный и статический
  • Const

см. подробный ответ на ваш вопрос




Ну, этот вопрос слишком стар, но так как никто не указывает какую-либо полезную информацию: проверьте сообщение «mohit12379», объясняя хранилище статических переменных с тем же именем в таблице символов: http://www.geekinterview.com/question_details/24745




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




Вот как (легко понять):




вы уже знаете, что он хранит в bss (запуск блока по символу), также называемый неинициализированным сегментом данных или в сегменте инициализированных данных.

давайте рассмотрим простой пример

void main(void)
{
static int i;
}

эта статическая переменная не инициализируется, поэтому она переходит в неинициализированный сегмент данных (bss).

void main(void)
{
static int i=10;
}

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




Related