I’m trying to process a large graph using a recursive algorithm. Due to the deep recursion, I encountered the problem described at Python: Maximum recursion depth exceeded.
So, I tried increasing the limit on recursion depth, like so:
import sys
sys.setrecursionlimit(5000)
However, whatever value I use for the depth, I cannot get the result I want. Either I still get the exception, or else the program just halts with no output on the screen but: Process finished with exit code -1073741571
.
How can I solve the problem?
See also: What is the hard recursion limit for Linux, Mac and Windows?
Karl Knechtel
62.3k11 gold badges102 silver badges153 bronze badges
asked Dec 17, 2013 at 8:12
Salvador DaliSalvador Dali
214k147 gold badges704 silver badges753 bronze badges
15
You could use something like:
if __name__ == '__main__':
sys.setrecursionlimit(100000)
threading.stack_size(200000000)
thread = threading.Thread(target=your_code)
thread.start()
This solved both my recursion limitation and my heap size limitation.
answered Aug 9, 2015 at 7:42
1
As some previous comments mentioned, you’re most likely running into a stack overflow issue here. The default stack size of a thread is platform dependent, so it makes sense that your code would result in a crash in certain environments, but work in others.
A possible way to have caught this issue would have been running it with AddressSanitizer enabled. For example (I have your code in «main.cc»):
$ g++ main.cc
$ ./a.out
Segmentation fault
$ g++ -fsanitize=address main.cc
$ ./a.out
ASAN:DEADLYSIGNAL
=================================================================
==224881==ERROR: AddressSanitizer: stack-overflow on address 0x7ffc3567b098 (pc 0x5586c57fe932 bp 0x7ffc39b5fd40 sp 0x7ffc3567b0a0 T0)
#0 0x5586c57fe931 in main (~/a.out+0x2931)
#1 0x7fddf00c052a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a)
#2 0x5586c57fe509 in _start (~/a.out+0x2509)
SUMMARY: AddressSanitizer: stack-overflow (~/a.out+0x2931) in main
==224881==ABORTING
For educational purposes only (I do NOT recommend actually doing this), we can observe your program working if we manually increase the stack limit. On Linux, if we insert
struct HackRunBeforeMain {
HackRunBeforeMain() {
// See http://man7.org/linux/man-pages/man2/getrlimit.2.html
// Not checking any errors to keep the example simple.
struct rlimit rlim;
getrlimit(RLIMIT_STACK, &rlim);
// Set the current thread's stack size to 1GB!
rlim.rlim_cur = 1024 * 1024 * 1024;
setrlimit(RLIMIT_STACK, &rlim);
}
};
HackRunBeforeMain hack_run_before_main;
into your program, running it does not result in a segfault (at least on my machine).
For a long term fix, you should look into ensuring that each matrix
‘s data is on the heap, rather than the stack. You can accomplish this via tools such as malloc
, new
, or std::make_unique<T>
. Modifying the original program to do so is left as an exercise to the asker.
CorreoTotal es un portal cuyo objetivo primordial es ofrecer guías y tutoriales sobre los principales servicios de streaming, redes sociales, correos electrónicos y otras plataformas utilizadas por los internautas.
Destacado
Outlook
▶️ Hotmail — Crear cuenta ✔️ Iniciar sesión y entrar al correo
Internet
Cómo desactivar imágenes en Internet Explorer para ahorrar datos
Internet
5 pasos para corregir el error 504 de Android al descargar aplicaciones
Internet
4 problemas comunes de Android y sus soluciones
Cómo configurar Google como motor de búsqueda predeterminado en Microsoft Edge, Chrome, Firefox, Opera, Safari
Desear Establecer Google como ¿Motor de búsqueda predeterminado en Safari, Opera, Chrome, Firefox, IE o Microsoft Edge? Hoy en día, la mayoría de los navegadores tienen motores de búsqueda predeterminados. Si lo deseas, puedes configurar…
Leer más
Las 3 principales configuraciones para arreglar Android no permanecen conectados al problema de Wi-Fi
Cuando tu Android no permanecerá conectado a Wi-Fi, puedes seguir mi solución. A veces tu teléfono o tableta Android puede mostrar un error el wifi no permanece conectado. Verá este error debido a algunos problemas…
Leer más
Cómo solucionarlo Desafortunadamente, los servicios de Google Play han sido descontinuados
Tomaste Lamentablemente, los servicios de Google Play han sido descontinuados. ¿error? No te preocupes, aquí encontrarás una solución. Este es un mensaje de error común en los teléfonos móviles con Android. Aquí proporcionaré algunas soluciones…
Leer más
Manera gratuita de duplicar CD de audio, copiar CD a MP3
Duplicación de CD de audio Es muy sencillo con software gratuito. Aquí explico cómo replicar CD de audio, cómo copiar CD a MP3, cómo copiar CD de música usando software gratuito. Anteriormente hablamos de Format…
Leer más
Prolongar la duración de la batería de Android: 7 consejos para ahorrar batería
Desear Ampliar la duración de la batería de Android. Aquí te daré el mejor consejo. aumenta la batería de tu teléfono Android. Estos Los consejos son muy útiles para prolongar la duración de la batería…
Leer más
Las 5 mejores alternativas de TeamViewer para compartir escritorio remoto
Desear Alternativas a Teamviewer? Sin duda, Teamviewer es el mejor software para compartir escritorio. Pero hay muchos otros programas gratuitos que funcionan mejor que Teamviewer. los 5 primeros alternativas a Teamviewer Será útil para quienes…
Leer más
39 atajos de teclado del navegador Google Chrome que debes conocer
Aquí le proporcionaré los atajos de teclado más útiles del navegador Google Chrome. Los atajos de teclado son útiles para trabajar sin mouse. Estos atajos de teclado de Google Chrome son útiles para mejorar las…
Leer más
Los 30 atajos de teclado más útiles para Opera
Aquí te daré los atajos de teclado Opera más útiles del navegador. Los atajos de teclado son útiles para trabajar sin mouse. Estos atajos de teclado de Opera son útiles para mejorar las habilidades de…
Leer más
Cómo instalar el navegador Mozilla Firefox en Windows
Aquí te proporcionaré pasos simples para Instalar Mozilla Firefox navegador en una PC con Windows. Este navegador es uno de los navegadores más rápidos para acceder a Internet. El procedimiento de instalación del navegador Mozilla…
Leer más
Во время программирования на C++ может возникнуть ряд ошибок, которые могут привести к сбоям программы. Одним из таких типов ошибок является код -1073741571 (0xC00000FD). Такой код ошибки может привести к тому, что программа просто завершится и вылетит. В данной статье мы рассмотрим, какие причины могут привести к данной ошибке и как её можно исправить.
Что значит код ошибки -1073741571 (0xC00000FD)?
Код ошибки -1073741571 (0xC00000FD) относится к типу ошибок, который называется stack overflow (переполнение стека). Это связано с тем, что каждая программа, которая работает на операционной системе Windows, выделяет определенный объем памяти для стека. Стек – это область памяти, которая используется для временного хранения данных во время выполнения функций.
Когда функция вызывается, она сохраняет свои переменные и адрес возврата на стек. Затем функция начинает работать и может вызывать другие функции. В этом случае, каждая новая функция выделяет стек с дополнительным объемом памяти. Если функция вызывает слишком много других функций или перекрывает слишком много памяти на стеке, то это может привести к переполнению стека.
Когда стек переполняется, программа вылетает и появляется код ошибки -1073741571 (0xC00000FD). Это происходит потому, что система не может обработать такое количество данных, которые сейчас находятся на стеке.
Как исправить ошибку -1073741571 (0xC00000FD)?
1. Перепроверьте логику своей программы
Переполнение стека часто связано с логическими ошибками в коде. Любой код, который требует дополнительных вызовов функций или обращений к стеку, может привести к данной ошибке. Вам нужно перепроверить код на наличие ошибок, которые могут привести к переполнению стека.
2. Увеличьте объем памяти стека
Если ваша программа содержит много функций или других операций, которые требуют большого объема памяти, то вы можете увеличить объем памяти стека. Для увеличения памяти стека можно использовать функцию _setmainstactksize().
3. Используйте динамическое выделение памяти вместо стека
Другой способ избежать переполнения стека – это использовать динамическое выделение памяти вместо стека. В отличие от стека, память, выделенная динамически, хранится в куче и не ограничена размером стека. Если ваш код использует много памяти на стеке, то вы можете перенести эту память в кучу.
4. Используйте профилировщики для поиска ошибок
Если вы все еще не можете найти ошибку, которая приводит к переполнению стека, вы можете использовать специальные профилировщики, которые помогут найти проблемные места в вашем коде. Профилировщики могут помочь определить, какие функции используют больше всего памяти и какая часть вашего кода является наиболее ресурсозатратной.
Вывод
Ошибка -1073741571 (0xC00000FD) может быть очень затруднительна для нахождения. Но с помощью различных инструментов и методов, описанных выше, это можно исправить. Помните, что переполнение стека возникает, когда программе требуется больше памяти, чем заложено в стеке. Для избежания этой ошибки необходимо использовать правильные методы выделения памяти и давать программе возможность использовать большой объем памяти, если это необходимо.
Поэтому я работаю над этой симуляцией, для которой я должен написать код.
Первоначально я получал код ошибки 255 (0xff), который, как я думал, мог быть связан с добавлением Eigen в мои блоки кода. Однако, как только я переместил свои собственные Eigen-заголовки в папку include блоков кода, я теперь получаю новую ошибку с сообщением:
Процесс завершен со статусом -1073741571 (0 минут, 2 секунд)
Я посмотрел эту ошибку, и она говорит, что она возникает, когда ошибка вызывает переполнение стека. Я запустил мой отладчик и получил сообщение:
Зарегистрирован новый тип: wxString
Зарегистрирован новый тип: STL String
Зарегистрирован новый тип: STL Vector
Установка точек останова Имя и версия отладчика: GNU GDB (GDB) 7.6.1
PID дочернего процесса: 13284
Программа получила сигнал SIGSEGV, Ошибка сегментации.
Таким образом, я знал, что есть ошибка с одной из моих функций.
Вот мой код (он довольно большой)
#include <iostream>
#include <fstream>
#include <conio.h>
#include <random>
#include<math.h>
#include <Eigen/Dense>
#include<time.h>
#define pi atan(1) * 4
using namespace std;
using namespace Eigen;
int Poisson(int N)
{
int n=1;
float x,y,k=0;
do
{
x=(float)rand()/RAND_MAX;
y = -log(x);
k=k+y;
n=n+1; //n increases for each random number generated
}
while(k<N);
return n;
}
int sumrow(MatrixXd A,int row, int col_len)
{
int sum=0;
for(int i=0;i<col_len;i++)
{
sum=sum+A(row,i);
}
return sum;
}
void generate_D(MatrixXd A, int dim, MatrixXd D)
{
for(int x=0;x<dim;x++)
{
for(int y=0;y<dim;y++)
{
if(x==y)
{
D(x,y)=1/sqrt(sumrow(A,x,y));
}
else
{ D(x,y) =0; }
}
}
}
void sqmatrix_multiply(MatrixXd A,MatrixXd B,int dim, MatrixXd C)
{
for(int i=0;i<dim;i++)
{
for(int j=0;j<dim;j++)
{
for(int k=0;k<dim;k++)
{
C(i,j) = C(i,j) + (A(i,k)*B(k,j));
}
}
}
}
void generate_B(MatrixXd A, int dim, MatrixXd B)
{
MatrixXd D;
MatrixXd C, inter1, inter2;
generate_D(A,dim,D);
sqmatrix_multiply(A,D,dim,inter1);
sqmatrix_multiply(D,C,dim,inter2);
for(int i=0;i<dim;i++)
{
for(int j=0;j<dim;j++)
{
if(i==j)
{
B(i,j) = 1 - inter2(i,j);
}
else
{
B(i,j) = 0 - inter2(i,j);
}
}
}
}
int main()
{
srand(time(NULL));
double X,Y,x,y,a,b,L[5000][5000],M[5000][5000];
MatrixXd A, B;
for(int i=0; i<5000;i++)
{ L[i][i]=0; M[i][i]=0; }
int N, I;
cout<<"Enter your number and iterations";
cin>>N>>I;
int P[5000];
for(int i=0; i<I; i++)
{
P[i]=Poisson(N);
}
for(int k=0; k<I; k++)
{
for (int j=0;j<P[k];j++)
{
A:
X=(float)rand()/RAND_MAX;
Y=(float)rand()/RAND_MAX;
x=sqrt(X);
y = 2*(pi)*Y;
a=x*cos(y);
b=x*sin(y);
if((a*a)+(b*b)>1)
{
goto A;
}
L[k][j] = a; M[k][j] = b;
}
}
for(int a=0;a<I;a++)
{
for(int a1=0;a1<P[a];a1++)
{
for(int a2=0;a2<P[a];a2++)
{
if(a1==a2)
{
A(a1,a2)=0;
}
else
{
if(((L[a][a1]-L[a][a2])*(L[a][a1]-L[a][a2]))+((M[a][a1]-M[a][a2])*M[a][a1]-M[a][a2]) < 1) //distance formula
{
A(a1,a2)=1;
}
else
{
A(a1,a2)=0;
}
}
}
}
generate_B(A,P[a],B);
EigenSolver<MatrixXd> b(B,false);
cout<<a+1<<" Eigen values are: \n "<<b.eigenvalues()<<"\n";
}
return 0;
}
Я опробовал несколько функций по отдельности в разных программах. Проблема не связана с заголовками Eigen, так как sumrow () работал отлично.
Однако функция Пуассона () выдала мне ту же ошибку (-1073741571). Я попытался заменить do-while простым, но это не сработало.
Ранее, когда я использовал Poisson () отдельно, он работал нормально. Но теперь, это не работает независимо друг от друга.
Извините за длинный вопрос, но я был на нем уже больше недели и не могу понять это. Если бы вы могли сказать мне, что, возможно, не так с моим кодом, я был бы очень благодарен.
Заранее большое спасибо!
0
Задача ещё не решена.