Форум программистов, компьютерный форум CyberForum.ru

при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? - C++

Восстановить пароль Регистрация
 
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
25.11.2011, 19:50     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? #1
Сабж
g++ 4.5.0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2011, 19:50     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"?
Посмотрите здесь:

абстрактные типы данных "СТЕК" и "ОЧЕРЕДЬ" C++
C++ Как сделать, чтобы функции работали "независимо" одна от другой?
C++ не меняя эту часть кода(она должна остаться точь-в-точь как выше) сделать так, чтоб запускаемое приложение выводило на экран "hello world!"
Как сделать чтобы при нажатии на кнопку "PlayWarcraft" заходил на мой сервер через IP adress C++
Как через "IF" сделать чтобы программа закрывалась после ввода неверного значения C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
25.11.2011, 20:51     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? #2
Сразу огорчу, нет универсального способа. Лучше менять алгоритм.
Хотя бы потому, что размер стека задается при компиляции и не известен программе во время исполнения.
В качестве костыля, можно ограничить его вручную.
Пример.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <string>
#include <iostream>
#include <exception>
 
static char *stackBegin;
static int stackSize;
 
int getStackSize() {
  char stackPosition;
  int currentStackSize = (&stackPosition) - stackBegin;
  if (currentStackSize < 0) currentStackSize = -currentStackSize;
  return currentStackSize;
}
 
long int stackEater(long int n) {
  if (getStackSize() < stackSize) {
    int result = stackEater(n + 1);
    return result;
  } else {
    return n;
  }
}
 
int main(int argc, char *argv[]) {
  char stackTop;
  stackBegin = &stackTop;
  stackSize = 120 * 1024;
  
  std::cout << stackEater(1) << std::endl;
  return 0;
}
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
25.11.2011, 21:05  [ТС]     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? #3
А если отвлечься от размера стека и воспользоваться тем, что при его переполнении ось генерит ошибку и от неё плясать? (Ведь генерит же она какую-то ошибку!) Тогда надо как-то будет эту ошибку "перехватить", типа GetLastError
Но вот беда, я ни разу с системными ошибками не работал.
LosAngeles
Заблокирован
25.11.2011, 21:49     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? #4
генерится SIGSEGV, перехватывается, как и любой другой сигнал(sigaction), только при этом не забыть назначить альтернативный стек, чтобы хэндлер мог выполниться(sigaltstack).

Добавлено через 16 минут
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/user.h>
 
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
 
 
static int count = 0;
 
void greedy() {
    char ch[1024 * 32];
    printf("%d\n", ++count);
    greedy();
}
 
 
int main(int argc, char *argv[]) {
    struct rlimit rlim;
    
    getrlimit(RLIMIT_STACK, &rlim);
    int x = rlim.rlim_cur / 1024 / 1024;
    printf("%d", x);
    rlim.rlim_cur *= 32;
    setrlimit(RLIMIT_STACK, &rlim);
    x = rlim.rlim_cur /1024 /1024;
    
    printf("%d", x);
    greedy();
    
    
    return 0;
}
а вот так вроде увеличивается стек. Стандартно у меня 8 метров было
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
25.11.2011, 22:00  [ТС]     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? #5
Спасибо, но я прочёл что В Windows сигналы SIGILL, SIGSEGV и SIGFPE не генерируются, а у меня Windows как раз
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
11.12.2011, 20:42  [ТС]     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"? #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
     #include <windows.h>
      #include <stdio.h>
       
      void k ()
      {
        printf ("hello, word!\n");
        k();
      }
       
       
      LONG WINAPI TopLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* except_info)
      {
        throw except_info;
      }
       
      int main ()
      {
       SetUnhandledExceptionFilter(TopLevelUnhandledExceptionFilter);
       
       try
       {
        k();
       }
       catch (PEXCEPTION_POINTERS except_info)
       {
        if (except_info->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
         printf ("Stack overflow exception\n");
         getchar ();
        }
        else printf ("Unexpected exception!\n");
       }
       return 0;
      }
Вот так можно. Правда, это видно по запуску из консоли, да и нигде ничё не сохраняется, но главное, что диагностирутеся правильнео, как и было заявлено.
Yandex
Объявления
11.12.2011, 20:42     при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"?
Ответ Создать тему
Опции темы

Текущее время: 01:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru