В чем разница между ошибкой сегментации и переполнением стека? - PullRequest
25 голосов
/ 21 апреля 2010

Например, когда мы вызываем, скажем, рекурсивную функцию, последовательные вызовы сохраняются в стеке. Однако из-за ошибки, если она длится бесконечно, это ошибка «Ошибка сегментации» (как видно из GCC).

Разве это не было переполнением стека? В чем же тогда основная разница между ними?

Кстати, объяснение было бы более полезным, чем ссылки на Википедию (прошло через это, но без ответа на конкретный запрос).

Ответы [ 4 ]

56 голосов
/ 21 апреля 2010

Переполнение стека - это [a] причина, ошибка сегментации - это результат.


По крайней мере на x86 и ARM "стек" - это часть памяти, зарезервированная для размещения локальных переменных и адресов возвратавызовов функций.Когда стек исчерпан, доступ к памяти за пределами зарезервированной области будет осуществляться.Но приложение не запрашивало у ядра эту память, поэтому для защиты памяти будет создан SegFault.

3 голосов
/ 21 апреля 2010

Современные процессоры используют диспетчеры памяти для защиты процессов друг от друга. Диспетчер памяти x86 имеет множество унаследованных функций, одной из которых является сегментация. Сегментация предназначена для того, чтобы программы не могли манипулировать памятью определенным образом. Например, один сегмент может быть помечен только для чтения, и код будет помещен туда, а другой сегмент - для чтения / записи, и именно туда отправляются ваши данные.

Во время переполнения стека вы исчерпываете все пространство, выделенное для одного из ваших сегментов, а затем ваша программа начинает записывать в сегменты, которые не разрешены диспетчером памяти, и затем вы получаете ошибку сегментации.

3 голосов
/ 21 апреля 2010

Стек вызовов переполняется, однако в результате переполнения в конечном итоге значения, связанные с вызовом, помещаются в память, которая не является частью стека, а затем - SIGSEGV!

2 голосов
/ 21 апреля 2010

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

...