Подтвердить что ты не робот

Почему переполнение стека на некоторых машинах, но ошибка сегментации на другом?

Просто из любопытства я пытаюсь создать переполнение стека. Этот код генерирует переполнение стека в соответствии с OP, но когда я запускаю его на своей машине, он генерирует ошибку сегментации:

#include <iostream>

using namespace std;

int num = 11;
unsigned long long int number = 22;

int  Divisor()
{
    int result;
    result = number%num;

    if (result == 0 && num < 21)
    {
        num+1;
        Divisor();

        if (num == 20 && result == 0)
        {
            return number;
        }
    }

    else if (result != 0)
    {
        number++;
        Divisor();
    }
}

int main ()
{
    Divisor();
    cout << endl << endl;
    system ("PAUSE");
    return 0;
}

Кроме того, согласно этой, некоторые примеры также должны сделать то же самое. Почему вместо этого возникают ошибки сегментации?

4b9b3361

Ответ 1

Почему вместо этого возникают ошибки сегментации?

Ошибка сегментации, что вы видите, является побочным эффектом. Причина - переполнение стека, результат - ошибка сегментации.

Из статьи в википедии для "переполнения стека" (выделено мной)

.... Когда программа пытается использовать больше места, чем доступно в стеке вызовов (то есть, когда она пытается получить доступ к памяти за пределами границ стека вызовов, что по сути является переполнением буфера), стек указан для переполнения, что обычно приводит к сбою программы .

Ответ 2

Переполнение стека может привести к следующим ошибкам:

  • SIGSEGV (нарушение сегментации) для процесса.
  • SIGILL (незаконная инструкция).
  • SIGBUS доступ к недопустимому адресу.

Подробнее читайте Сигналы ошибки программы. Поскольку поведение undefined, любое из вышеперечисленных может возникнуть на разных системах/архитектурах.

Ответ 3

Вы, по сути, спрашиваете: каково поведение поведения undefined?

Ответ: undefined поведение - это поведение, которое не определено. Все может случиться.

Исследование того, почему вы получаете определенное поведение undefined в определенной системе, чаще всего бессмысленно.

Undefined, неопределенное и определяемое реализацией поведение

В случае программа может перезаписать другие переменные в ОЗУ или испортить собственный обратный адрес текущей функции или попытаться изменить память за пределами заданного диапазона адресов и т.д. В зависимости от системы вы можете получить аппаратные исключения и различные сигналы ошибок, такие как SIGSEGV (в системах POSIX) или внезапные сбои программы, или "программа, кажется, работает нормально" или что-то еще.

Ответ 4

Другие опубликованные ответы правильны.

Однако если цель вашего вопроса состоит в том, чтобы понять, почему вы не видите напечатанную ошибку, заявив, что произошло переполнение стека, ответ заключается в том, что некоторые библиотеки времени выполнения явно обнаруживают и сообщают о переполнении стека, в то время как другие не, и просто сбой с segfault.

В частности, похоже, что хотя бы некоторые версии Windows обнаруживают Stackoverflows и превращают их в исключения, поскольку документация предлагает вам справиться с ними.

Ответ 5

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

В Linux и других подобных UNIX системах segmentation fault может быть, в частности, результатом. Вы не получаете никакой конкретной информации о том, что программа столкнулась с переполнением стека.

В первом сообщении, которое вы связываете, человек запускает код в Windows, который может вести себя по-другому, и, например, обнаруживать переполнение стека.

Ответ 6

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

Проверка стека - довольно простой механизм, он убивает программу, заявляя, что переполнение стека произошло, как только указатель стека пролетел мимо привязки стека. Он часто отключается для целей оптимизации, потому что программа почти наверняка будет разбита на переполнение стека в любом случае.

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