1) Строка не (обычно) в стеке - обычно она находится в инициализированном сегменте данных, который читается непосредственно из исполняемого файла. Затем указатель инициализируется по адресу этой строки.
2) Нет.
3) Потому что стандарт говорит, что он дает неопределенное поведение. Подумайте, было ли у вас что-то вроде этого:
int a() { char *a = "a"; printf("%s\n", a); }
int b() { char *b = "a"; *b = 'b'; }
int main() {
b();
a();
return 0;
}
Теперь, когда вы печатаете a
, ожидаете ли вы получить исходное значение (a) или обновленное значение (b)? Компиляторы могут, но не обязательно, совместно использовать такие статические строки; некоторые также помечают всю область только для чтения, поэтому попытка записи в нее приведет к исключению.
С точки зрения стандарта C единственным разумным ответом было назвать его неопределенным поведением.