Является ли этот код неопределенным поведением? Как насчет ОС и кучи? Как ОС обрабатывает стек? - PullRequest
0 голосов
/ 27 августа 2011
char * s;
s[400] = 'd';

Если это не неопределенное поведение, значит ли это, что я не могу произвольно получить доступ к какой-либо части моей оперативной памяти вне стека?Поэтому каждый раз, когда ОС запускает процесс, она выделяет область оперативной памяти, где я могу делать неприятные вещи (кроме malloc), поскольку ОС завершит очистку стека после завершения процесса.

Почему не ОСв состоянии очистить кучу после завершения процесса?Означает ли это, что куча используется совместно со всеми другими процессами?

Если я помещаю слишком много данных в стек, это переполнение буфера, но сколько я могу поместить в стек?Связано ли это с ОС, размером ОЗУ или кэшем ЦП?

Ответы [ 2 ]

5 голосов
/ 27 августа 2011

Да, его поведение не определено.

s не инициализируется, поэтому s[400] в лучшем случае является неопределенным местом в памяти.

EDIT:

Последние три абзаца вашего вопроса не имеют ничего общего с двумя строками кода, которые мы обсуждали. Неопределенность s[400] = 'd'; не имеет ничего общего со стеками, кучами, процессами или чем-то еще. s неинициализирован, поэтому содержит мусор; это может указывать где-нибудь в памяти или нигде. s[400] в лучшем случае это объект типа char, расположенный в 400 байтах за пределами неопределенного местоположения, указанного в хранимом адресе мусора: s.

Если вы понимаете это, у вас, вероятно, еще есть вопросы. Я предлагаю опубликовать новый вопрос без примера кода.

К частично ответить на некоторые вопросы, которые вы спросили:

Ваша программа не может законно пытаться получить доступ к любой памяти, которая не является частью объекта, который она создала (либо с помощью определения объекта, например char foo[1000];, либо с помощью выделения, например char *ptr = malloc(1000);). В конкретной реализации может быть некоторой областью памяти вне любых объявленных объектов, с которыми вам может быть удобно играть, но не существует безопасного или переносимого способа сделать это - и нет веской причины. Если вам нужно получить доступ к некоторой памяти, сначала выделите ее.

Сам язык C даже не ссылается на "стек" или "кучу"; это детали реализации.

Нет, куча обычно не разделяется между процессами. Как правило, вся выделенная в стеке и в куче память аккуратно восстанавливается операционной системой после завершения вашей программы. (Стандарт C не говорит об этом, поскольку он только касается того, что происходит за пределами исполнения вашей программы, но это почти всегда верно, за исключением, возможно, некоторых встроенных систем.)

3 голосов
/ 27 августа 2011

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

...