Я много искал это решение, но не повезло вообще.
Вот основы моей программы. У меня есть цикл в моей основной функции. Цикл должен вычислять много данных, и в итоге он переполняется, когда я присваиваю одной из моих переменных значение больше 20.
Я знаю, что всякий раз, когда вы делаете «возврат» в функции, она освобождает весь стек. Вот в чем дело, мне нужен этот цикл, чтобы он работал вечно, пока человек не закроет приложение.
Это вообще возможно? Все ли функции требуют короткого срока службы до того, как произойдет переполнение стека? Если я использую динамическую память, я все равно не смогу избавиться от других данных стека, которые он накапливает при каждом запуске.
В принципе, как я могу запустить функцию навсегда, не заканчивая переполнением стека?
Стек имеет ограниченный размер. В некоторых системах Windows это 1 МБ. Вы можете программно изменить размер стека, но чаще всего это плохая идея.
У вас разные стеки в каждом потоке. Переменные стека всегда освобождаются в конце области. Например.
void MyFunction
{ // begin of scope 1
std::string mouse("feep");
for (int i = 0; i < 10000000; i++)
{ // begin of scope 2
int x = 1; // x is on the stack
std::string cow("moo"); // cow is on stack
// end of scope 2, cow is destroyed then the stack is freed for cow and x before the next iteration of the loop begins
}
return; // end of scope 1, mouse is destroyed ant the stack is freed for mouse
}
В любой момент приведенный выше код mouse
, i
, x
, а также cow
в стеке. Если вы используете рекурсия Вы можете получить очень глубокий стек, который переполняется. Например.
void StackOverflowIncoming()
{ // begin of scope
int aVariableOnTheStack = 0;
StackOverflowIncoming();
// end of scope
}
Вышеприведенная функция открывает новые области действия навсегда и никогда не покидает область действия, поэтому в какой-то момент она будет переполнена.
Еще один способ переполнить стек alloca
, который непосредственно выделяет стек (который затем освобождается, как только закрывается область, в которой он был выделен. Просто используйте alloca
выделить 10 МБ в стеке, если максимальный размер стека составляет 1 МБ. Этого также можно достичь, разместив огромную структуру в стеке.
void InstantStackOverflow()
{
char buffer[1<<24];
}
Для более подробного примера размещения слишком большого количества в стеке посмотрите это вопрос.
Последний и самый творческий способ переполнить стек — это испортить состояние программы, чтобы программа ужасно запуталась и не смогла очистить стек. Обычно вы делаете это, используя языковые функции, которые приводят к неопределенному поведению, например так:
void TryToCorruptTheStack()
{ // begin of scope
char buffer[1];
for (int i = -20; i < 20; i++)
buffer[i] = 5;
// end of scope
}
Более подробный пример повреждения стека смотрите здесь вопрос.
Запуск функции не заполняет стек. Однако, если вы используете рекурсивный вызов функции, да, в конечном итоге стек переполнится. Возвращаясь к вашему вопросу — вы говорите, что запускаете цикл в главной функции, который вызывает переполнение стека, а затем говорите, что вызов функций вызывает переполнение стека. Циклы не могут вызвать переполнение стека, если вы не создаете в них новые объекты! Опять же, в C / C ++ главная функция не может называться рекурсивной. Вы не ясный друг.
Было бы здорово, если бы вы могли поделиться примером кода.
PS: это забавно, мы говорим о stackoverflow на stackoverflow: P