2014-11-28 2 views
4

Как я просматривал организации памяти и хранения в C/C++ Я наткнулся на это:.Статическая и глобальная переменная прояснение хранения

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

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

(найдено в http://www.geeksforgeeks.org/memory-layout-of-c-program/)

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

+4

Неверно, точка статической переменной заключается в том, что ее время жизни равно времени жизни программы. Он может быть изменен в любое время (если не объявлено const). (PS: Вы могли бы легко ответить на свой вопрос, написав код, который изменяет статическую переменную). – Borgleader

+0

Я думал об этом сам, но затем появился следующий вопрос: если я могу изменить содержимое переменной, написав код , не считается ли это временем компиляции, а не временем выполнения? – AutomEng

+0

... Если изменения происходят из-за того, что код работает, это время выполнения. Это только время компиляции, если это происходит * во время компиляции *. – Borgleader

ответ

5

Могут ли они быть изменены во время выполнения?

Да. Если вы не объявите их const, конечно.

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

Нет, вы описываете константы. Переменные с так называемым статическим временем хранения имеют, как следует из названия, другое время жизни. [Basic.stc.static]:

Все переменные, которые не имеют динамический срок хранения, не имеют срок хранения нити, а не местные имеют статического хранения продолжительность. Хранение данных объектов должно длиться программы (3.6.2, 3.6.3).

Просто подумайте о cout, глобальном объекте потока, который вы изменяете, вставляя в него данные.

+0

Спасибо, это было очень полезно. – AutomEng

2

Вы вообще найти лучшую документацию на сайте, что все больше людей принимают интерес к обновлению, к примеру - from Wikipedia:

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

Сегмент данные для чтения и записи, так как значения переменных могут быть изменены во время выполнения.Это в отличие от сегмента данных только для чтения (rodata сегмент или .rodata), который содержит статические константы, а не переменные; он также контрастирует с сегментом code, также известным как сегмент text, который доступен только для чтения на многих архитектурах. Неинициализированные данные, как переменные, так и константы, вместо этого находятся в сегменте BSS.

Таким образом, это просто вопрос определения:

  • сегмент данных содержит переменные для чтения и записи

  • «чтение только» сегмент данных содержит константы

В некоторых старых/хоккейных системах они могут быть не только с сегментом чтения только для чтения, но и просто скомбинировать его вместе - основной тонкий g с сегментом только для чтения, это означает, что несколько ошибок сообщаются более резко, вместо того, чтобы позволить программе испортить эти данные и потенциально вырвать фиктивные результаты. Вероятно, поэтому .data является общим, а когда-то позже - поскольку у авторов OS/компилятора было время и мотивация к уходу - .rodata оказался контрастирующим с ним, но .data не был переименован, например. .rwdata. Эти имена - .data, .rodata, test, BSS и т. Д. Были и используются в языках ассемблера для обозначения того, где должны располагаться переменные.

Что касается вещей ... глобальные переменные и переменные static аналогичны тем, что возможно [возможно, виртуальный] адрес памяти для них - и даже их общий размер - могут быть вычислены (по крайней мере, относительно некоторого поддерживающего процессора) сегментный "регистр, который оставлен на удобном значении большую часть времени) во время компиляции. Это контрастирует с автоматическими (стек) и динамическими (кучи) переменными, где переходный период памяти. Большинство систем имеют контроль над доступом для записи в память на основе каждой страницы (например, 4k, 8k), поэтому гораздо менее практично продолжать предоставлять и удалять доступ на запись, чтобы помещать переходные переменные const в память, что кажется только для чтения для процесса, и это непрактично, когда вы рассматриваете условия гонки в многопоточном приложении. Вот почему это различие между памятью «чтение-запись» и «только для чтения» обычно обсуждается в контексте глобальных и статических переменных.