Да, его поведение не определено.
s
не инициализируется, поэтому s[400]
в лучшем случае является неопределенным местом в памяти.
EDIT:
Последние три абзаца вашего вопроса не имеют ничего общего с двумя строками кода, которые мы обсуждали. Неопределенность s[400] = 'd';
не имеет ничего общего со стеками, кучами, процессами или чем-то еще. s
неинициализирован, поэтому содержит мусор; это может указывать где-нибудь в памяти или нигде. s[400]
в лучшем случае это объект типа char, расположенный в 400 байтах за пределами неопределенного местоположения, указанного в хранимом адресе мусора: s
.
Если вы понимаете это, у вас, вероятно, еще есть вопросы. Я предлагаю опубликовать новый вопрос без примера кода.
К частично ответить на некоторые вопросы, которые вы спросили:
Ваша программа не может законно пытаться получить доступ к любой памяти, которая не является частью объекта, который она создала (либо с помощью определения объекта, например char foo[1000];
, либо с помощью выделения, например char *ptr = malloc(1000);
). В конкретной реализации может быть некоторой областью памяти вне любых объявленных объектов, с которыми вам может быть удобно играть, но не существует безопасного или переносимого способа сделать это - и нет веской причины. Если вам нужно получить доступ к некоторой памяти, сначала выделите ее.
Сам язык C даже не ссылается на "стек" или "кучу"; это детали реализации.
Нет, куча обычно не разделяется между процессами. Как правило, вся выделенная в стеке и в куче память аккуратно восстанавливается операционной системой после завершения вашей программы. (Стандарт C не говорит об этом, поскольку он только касается того, что происходит за пределами исполнения вашей программы, но это почти всегда верно, за исключением, возможно, некоторых встроенных систем.)