C сам по себе не имеет понятия сегментов (и дальних указателей), это будет особенностью базовой реализации или архитектуры (которую вы не указали). Сегментированные архитектуры и почти / далеко / крошечные указатели являются древними вещами 80-х годов - в настоящее время большинство кода (за возможным исключением встроенных компонентов) дает вам модель плоской памяти, в которой вам не нужно об этом беспокоиться.
Все стандартные условия состоят в том, что фактические символы строки будут символами, которые вы не можете изменять.
За то, что это стоит (что не так много). моя реализация хранит саму строку в памяти, помеченной только для чтения (это может быть или не быть сегментом кода, другие сегменты могут быть помечены только для чтения), и p
(адрес первого из этих символов) помещается в стеке во время выполнения.
Если вы запустите свой компилятор для вывода ассемблера:
gcc -S qq.c
вы увидите что-то вроде (в qq.s
в моем случае):
.file "qq.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "mystring\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
call __alloca
call ___main
movl $LC0, -4(%ebp)
movl $0, %eax
leave
ret
Из этого видно, что он находится в своем собственном разделе rdata
(данные только для чтения), а не в разделе text
.
Возможный недостаток помещения его в text
состоит в том, что такие вещи, как DEP (защита выполнения данных), будут намного сложнее.
Вы хотите, чтобы и код, и данные только для чтения были доступны только для чтения, но вы также хотите, чтобы код был исполняемым - вы не обычно хотите, чтобы данные только для чтения были исполняемыми.