Не используя рекурсию, как исключение из-за переполнения стека может быть брошено?

Я выяснил один способ сделать это.

кварта позволяет Вам передавать произвольные параметры конфигурации, которые можно использовать для разделения целей.

При наличии условной конфигурации в Вашем файле проекта:

CONFIG(myX64, myX64|myX32) {
    LIBPATH += C:\Coding\MSSDK60A\Lib\x64
} else {
    LIBPATH += C:\Coding\MSSDK60A\Lib
}

и передача, что пользовательская конфигурация к qmake с

qmake CONFIG+=myX64

Вы получаете требуемый результат.

7
задан Ether 22 February 2010 в 05:52
поделиться

9 ответов

Если вы вызовете достаточно методов, переполнение стека может произойти в любой момент. Хотя, если вы получаете ошибки переполнения стека без использования рекурсии, вы можете переосмыслить, как вы это делаете. С рекурсией это так просто, потому что в бесконечном цикле вы вызываете множество методов.

12
ответ дан 6 December 2019 в 04:46
поделиться

Поскольку никто об этом не упомянул:

throw new System.StackOverflowException();

Вы можете сделать это при тестировании или выполнении ввода неисправностей.

20
ответ дан 6 December 2019 в 04:46
поделиться

Следующее применимо к Windows, но большинство ОС реализуют это аналогичным образом.

Короткий ответ: если вы коснетесь последней страницы защиты, она выдаст.

исключение типа EXCEPTION_STACK_OVERFLOW (C00000FD) возникает, когда ваше приложение касается нижней страницы стека, которая помечена флагом защиты PAGE_GUARD , и нет места для увеличения стека (зафиксировать еще одну страницу), см. Как отловить переполнение стека в приложении Visual C ++ .
Типичный случай, когда это происходит, - когда стек вырос в результате большого количества функциональных кадров в стеке (т. Е. Неконтролируемая рекурсия), в результате меньшего количества кадров, но очень больших размеров кадра (функции с очень большой локальной областью объект) или явно выделяя его из стека с помощью _alloca .
Другой способ вызвать исключение - просто намеренно прикоснуться к странице защиты, например. путем разыменования указателя, указывающего на эту страницу. Это может произойти из-за ошибки инициализации переменной.

Переполнение стека может произойти на допустимых путях выполнения, если вход вызывает очень глубокий уровень вложенности. Например, см. Переполнение стека происходит, когда вы запускаете запрос, содержащий большое количество аргументов внутри предложения IN или NOT IN в SQL Server.

7
ответ дан 6 December 2019 в 04:46
поделиться

Объявить массив ENORMOUS как локальную переменную .

17
ответ дан 6 December 2019 в 04:46
поделиться
int main()
{
  //something on the stack
  int foo = 0;
  for (
    //pointer to an address on the stack
    int* p = &foo;
    //forever
    ;
    //ever lower on the stack (assuming that the stack grows downwards)
    --p)
  {
    //write to the stack
    *p = 42;
  }
}
0
ответ дан 6 December 2019 в 04:46
поделиться

Самый простой способ создать исключение StackOverflowException следующий:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeClass instance = new SomeClass();
            string name = instance.Name;
        }
    }

    public class SomeClass
    {
        public string Name
        {
            get
            {
                return Name;
            }
        }
    }
}
-1
ответ дан 6 December 2019 в 04:46
поделиться

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

Обратите внимание, что в системах с ограниченным объемом памяти (мобильные устройства и т. Д.) У вас не так много места в стеке, и оно закончится. раньше.

2
ответ дан 6 December 2019 в 04:46
поделиться

Если вы говорите о C ++ с разумной стандартной библиотекой, я полагаю, что это сработает:

while (true) {
    alloca(1024 * 1024); // arbitrary - 1M per iteration.
}

Подробная информация о alloca .

1
ответ дан 6 December 2019 в 04:46
поделиться

Краткий ответ: если у вас есть объект, который вызывает внутренний объект, вы увеличиваете трассировку стека на 1. Итак, если у вас есть тысячи объектов, вложенных друг в друга, каждый из которых вызывает свой внутренний объект, в конечном итоге вы получите переполнение стека.

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

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();

            IEnumerator<int> primes = p.AllPrimes().GetEnumerator();
            int numberOfPrimes = 1000;
            for (int i = 0; i <= numberOfPrimes; i++)
            {
                primes.MoveNext();
                if (i % 1000 == 0)
                {
                    Console.WriteLine(primes.Current);
                }
            }
            Console.ReadKey(true);
        }

        IEnumerable<int> FilterDivisors(IEnumerator<int> seq, int num)
        {
            while (true)
            {
                int current = seq.Current;
                if (current % num != 0)
                {
                    yield return current;
                }
                seq.MoveNext();
            }
        }

        IEnumerable<int> AllIntegers()
        {
            int i = 2;
            while (true)
            {
                yield return i++;
            }
        }

        IEnumerable<int> AllPrimes()
        {
            IEnumerator<int> nums = AllIntegers().GetEnumerator();
            while (true)
            {
                nums.MoveNext();
                int prime = nums.Current;
                yield return prime;

                // nested iterator makes a big boom     
                nums = FilterDivisors(nums, prime).GetEnumerator();
            }
        }
    }
}

Рекурсии нет, но программа выдаст исключение переполнения стека примерно после 150 000 простых чисел.

2
ответ дан 6 December 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: