Вопрос

В C++ спецификатор класса хранения static выделяет память из области данных.Что означает «область данных»?

Это было полезно?

Решение

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

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

Другие советы

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

В классическом понимании между ними нет разницы.Однако многие современные операционные системы могут запрещать выполнение кода в сегменте данных (при условии, что ЦП поддерживает это различие).Иногда это называется крылатой фразой «флаг NX», например «нет выполнения», и может эффективно предотвратить некоторые случаи внедрения вредоносного кода.

/РЕДАКТИРОВАТЬ:Обратите внимание, что стандарт C++ не упоминает «область данных».

Названия областей различаются в зависимости от платформы, компилятора и компоновщика.

В целом есть:

  • текст программы:Пространство исполняемого кода.
  • константы:Неисполняемые константы.
  • куча:Стек.
  • бсс:В широком смысле «статика» в терминах C/C++.«Блок, начатый символом»
  • данные:Неинициализированные глобальные переменные
  • куча:Память, выделяемая во время выполнения.

В этом случае в рассматриваемой документации используется имя «область данных» для того, что традиционно называется сегментом bss.

В терминах C спецификатор класса памяти «статический» означает память, которая существует на протяжении всего времени существования программы и инициализируется нулем или значением инициализатора.В примере:

static int s_value_one;
static int s_value_two = 123;

Значение s_value_one гарантированно равно нулю, а значение s_value_type равно 123 в точке первого оператора main().То, как это осуществится, является вопросом реализации.

Что сказал Конрад.

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

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

Немного погуглив, я нашел дополнительную информацию по этим темам здесь:

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

Исполняемый файл содержит много информации.

Исполняемый файл имеет множество типов/классов данных, хранящихся внутри его физического файла.

например, это

  1. Инструкции исполняемого кода
  2. Ресурсы
  3. Информация о зависимостях (от каких библиотек зависит этот двоичный файл)
  4. Символы, экспортированные из этого двоичного файла

и т. д.

Должен быть какой-то способ организовать

вся эта информация находится в формате файла .exe, чтобы ОС могла легко найти всю информацию, загрузить исполняемый файл и заставить все работать.Для этой цели в мире Windows используется общий двоичный формат (конечно, созданный M$), называемый PE (portable Executable).Вся информация, которую я только что перечислил (и многое другое), подробно описана в различных разделах двоичного файла.

раздел .data

Одним из таких разделов является раздел .data.Раздел .data содержит все инициализированные глобальные и статические данные, а раздел .bss — неинициализированные глобальные данные.

Почему вам нужен отдельный раздел для глобальных переменных?

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

Компилятор

Поэтому эти переменные должны быть размещены по некоторому постоянному адресу в куче, который, к сожалению, не может быть известен во время компиляции.Таким образом, компилятор помещает все глобальные и статические переменные в этот раздел .data/.bss, а инструкции, которые ссылаются на эти переменные, ссылаются на эти относительно постоянные адреса в .data/.bss.

Линкер

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

Теперь вы знаете, что такое раздел/область .data и почему глобальным переменным необходимо выделить некоторое пространство в этой области и как это помогает программе в режиме реального времени.Погуглив формат PE, компоновщик, раздел .data и т. д., вы получите ссылки.

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

Или это означает, что память, выделенная для этой переменной, находится в разделе .data исполняемого файла, но это специфично для Windows и формата PE.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top