@1q2w1q2w
sudo make install

Как исправить Stack Overflow при рекурсии с использованием std::thread и templates?

Код ниже:
#include <iostream>
#include <algorithm>
#include <locale>
#include <exception>

using namespace std;

double last_pos = 0x00;
int N = 0x00;

void str_cut()
{	++last_pos; // падает на == 3805
	
	if (last_pos > 64*1024) {
		return;			// exit condition
	}
	else {
		try {
			str_cut();	// Move semantics ONLY!
		}
		catch (std::exception const& e) {
			throw exception{};
			cerr << "Stack Overflow detected!" << /*e << */endl;
		}
	}

}

int main()
{
	try {
		// UTF-8 settings here
		setlocale(LC_ALL, "");
		setlocale(LC_ALL, "rus");

		std::cout.flush();
		str_cut();

		system("pause");
		return 0;

	}
	catch (...) {
		// stack overflow exception handling
		throw exception{};
		cerr << "Stack Overflow detected!" << /*e << */endl;
	}

}


Программа падает с Stack Overflow.
Упростил все для наглядности, теперь видно что происходит тупо превышение глубины стека (почему именно около 4000 вызовов?)
*Передачу по значению исправил с помощью move-семантики, утечек больше нет!
Но, как я понимаю, рекурсию придется убирать, хотя бы вот так:
while(last_pos < 65535) str_cut();

И сопутствующие вопросы:
1) Достаточно ли того, что я установил в начале программы локаль для работы с utf-8? (обрабатывать русские символы и т.д.)
2) Как в данном случае правильно обработать исключения?

ЗЫ: Буду рад любым советам!
  • Вопрос задан
  • 1968 просмотров
Решения вопроса 2
Не вчитывался в алгоритм, но, если верно понимаю, чем меньше N, тем больше глубина рекурсии, оттуда и stack overflow. Дело не во входной последовательности, а в локальных переменных и аргументах функции. Так что меняйте на цикл.

Что касается Access Denied и прочих, скорее всего другие ошибки есть.
Ответ написан
Комментировать
maaGames
@maaGames
Погроммирую программы
N - количество символов, но не глубина рекурсии. Если есть ошибка в алгоритме, например, он зацикливается, то переполнение стека произойдёт даже если под стек выделить всю память, включая дисковую и с рядом стоящего компьютера тоже.
Создай глобальную переменнную и увеличивай её значение при каждом входе в функцию str_cut и уменьшай значение при выходе (лучше сделай для этих целей класс, чтобы деструктор сам уменьшал значение). В момент падения посмотри значение, оно будет показывать реальную глубину рекурсии.

Типа такого код добавить надо:

int counter = 0;

class Counter
{
public:
   Counter( int & c )
: counter(c)
{
  ++counter;
}
~Counter()
{
  --counter;
}
int & counter;
};


str_cut()
{
  Counter _(counter);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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