Строковый литерал на С++ создается в статической памяти?

Строковый литерал в С++ создается в статической памяти и уничтожается только при выходе из программы?


person yesraaj    schedule 08.12.2008    source источник


Ответы (4)


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

В старые времена компилятора у вас были статические данные, такие как эти литералы, и глобальные, но изменяемые данные. Они были сохранены в сегменте TEXT (код) и сегменте DATA (инициализированные данные).

Даже если у вас есть такой код, как char *x = "hello";, сама строка hello хранится в памяти только для чтения, а переменная x находится в стеке (или где-то еще в доступной для записи памяти, если она глобальная). x просто устанавливается на адрес строки hello. Это позволяет выполнять всевозможные хитрости, такие как свертывание строк, так что «недопустимая опция» (0x1000) и «допустимая опция» (0x1002) могут использовать один и тот же блок памяти следующим образом:

+-> plus:0   1   2   3   4   5   6   7   8   9   A   B   C   D   E
|      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+----+
0x1000 | i | n | v | a | l | i | d |   | o | p | t | i | o | n | \0 |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+----+

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

Они также никогда не уничтожаются, пока не выйдет main().

person paxdiablo    schedule 08.12.2008
comment
Сегмент BSS всегда содержал только обнуленные, но непостоянные данные; данные, инициализированные ненулевыми значениями, находились в сегменте DATA. - person Jonathan Leffler; 05.08.2011
comment
@Destructor, я предполагаю, что это был комментарий к ответу Джеймса Хопкина. Это ответ, который утверждает, что строковые литералы действительны на протяжении всей программы, даже во время уничтожения статических объектов. Ни мой ответ, ни ответ на раскрутку (другой, на который вы написали этот комментарий) не оспаривают этого, но, по крайней мере, вы окружили Джеймса :-) - person paxdiablo; 21.02.2017

Да, строковые литералы действительны на протяжении всего времени работы программы, даже во время уничтожения статических объектов.

2.13.4/1 в Стандарте сказано

Обычный строковый литерал имеет тип "массив n const char" и статическую продолжительность хранения.

Стандарт говорит о «статической продолжительности хранения» в 3.7.1/1:

Хранилище для этих объектов должно длиться в течение всего срока действия программы.

person James Hopkin    schedule 08.12.2008

Ну да. Они как бы должны быть; информация, которая составляет последовательность символов в каждой строке, должна где-то находиться. Если бы они распределялись динамически, а затем инициализировались, где бы находилась информация, используемая для инициализации? Таким образом, более эффективно просто сделать строки статическими, чтобы они всегда были доступны и действительны после завершения загрузки программы.

person unwind    schedule 08.12.2008

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

person Samiksha    schedule 08.12.2008
comment
Вероятно, но не обязательно. Соответствующая реализация может хранить строковые литералы в памяти для чтения и записи. Любая программа, которая может определить разницу, в любом случае имеет неопределенное поведение. Конечно, хранить их в постоянной памяти — хорошая идея (если базовая система поддерживает это). - person Keith Thompson; 15.09.2011