То, где он создан, на самом деле является решением реализации автора компилятора. Скорее всего, строковые литералы будут храниться в сегментах памяти только для чтения, поскольку они никогда не меняются.
В старые времена компилятора у вас были статические данные, подобные этим литералам, и глобальные, но изменяемые данные. Они были сохранены в сегменте 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()
не выйдет.