Hola a todo el que lo lea.
Escribo en el foro a causa de un programa que he escrito en lenguaje c++. La causa es que tengo un problema y tras una búsqueda algo ligera con la ayuda de san google, no he encontrado a nadie que tuviese el mismo problema que yo.
He aquí el problema:
Al ejecutar el programa, tras estar un tiempo funcionando, este se cierra drásticamente. La solución no es poner un getchar() al final ni nada parecido. El programa funcionaba bien hasta que añadí algunas líneas de código. Al compilar no avisa de ningún error ni tampoco "warnings". Dado que el programa tiene unas 2000 líneas netas, no veo plausible el poner el código. La respuesta que busco son las razones por las que un ejecutable podría terminar su ejecución de forma drástica sin haber llegado al final del programa, y en un segundo plano las claves para solucionarlo.
Un saludo y muchas gracias de antemano.
Acceder a un puntero invalido es un ejemplo pero no vale la pena teorizar en estos casos, lo que tenes que hacer es depurar tu programa, te recomiendo usar el WinDbg.
Gracias por la respuesta. Voy a probar con esto que me dices.
Un saludo.
Cita de: Eternal Idol en 3 Septiembre 2013, 19:26 PMlo que tenes que hacer es depurar tu programa, te recomiendo usar el WinDbg.
CitarEl programa funcionaba bien hasta que añadí algunas líneas de código.
Aunque es evidente te comento que deberías empezar por depurar la zona de código que añadiste y, si no se soluciona, continúa por funciones, métodos y rutinas que sean llamadas por dichas líneas.
Saludos.
Un método (algo chapuzero) es poner un getchar() al principio del codigo, si funciona hasta el getchar() ve avanzando. De esa forma identificaras la línea que da problemas.
Lo más probable que sea algún puntero.
Hola otra vez.
Gracias por todas las respuestas, pero no he logrado resolver el problema. Con la ayuda de WinDbg si he podido saber que el problema se debe a un "stack overflow", pero no logro encontrar el lugar donde sucede. ¿Hay algún método para que WinDbg me diga en qué línea de código se encontraba cuando se produce el overflow?
En realidad ojalá fuese tan fácil como colocar un getchar(), pero en mi caso se trata de un programa de estadística: lo que hago es repetir una cosa muchas veces y a partir de muchos resultados sacar conclusiones, por lo que puedo pasar 40 veces por una línea y no obtener ningún fallo, pero a la que hace 41...
En fin que lo que me está llevando de cabeza es el encontrar la línea en la que se produce el overflow. Si a alguien se le ocurriese algo le estaría muy agradecido.
Un saludo.
Un stack overflow no se produce en una linea util digamos, la ultima instruccion que mueva algo a la pila sera la que termine por explotar PERO el problema esta en todas las anteriores, dale un kb ffff para ver la pila completa. ¿Estas usando alguna funcion recursiva por casualidad?
Vaya. Pues si, efectivamente estoy usando una función recursiva. Pero me parecería raro que fuese ahí el fallo porque únicamente le introduje unas variables nuevas que uso para comparar en condicionales...
Cita de: pABL012 en 5 Septiembre 2013, 12:13 PM
Vaya. Pues si, efectivamente estoy usando una función recursiva. Pero me parecería raro que fuese ahí el fallo porque únicamente le introduje unas variables nuevas que uso para comparar en condicionales...
Si los condicionales están mal diseñados y permiten que se sigua llamando de forma recursiva a la función cuando no deberían...
Tu piensa que cada llamada a una función supone meter datos en la pila. Una llamada recursiva que se llame a sí misma de forma descontrolada implica que la pila antes o después se va a desbordar... cuando eso pasa tu programa muere.
Estoy seguro de que no se llama de forma descontrolada a la función. Como ya digo, el programa pasa por esas líneas unas 40 veces antes de morir... no se me ocurre que hacer, la verdad
Es necesario que una función se llame de forma recursiva 40 veces ???
Lo mismo sería más lógico que no fuese recursiva y encerrar ese código en un bucle.
Cita de: pABL012 en 5 Septiembre 2013, 12:13 PM
Vaya. Pues si, efectivamente estoy usando una función recursiva. Pero me parecería raro que fuese ahí el fallo porque únicamente le introduje unas variables nuevas que uso para comparar en condicionales...
Listo, el problema esta ahi sin duda, lo mas probable es que la condicion que hacia retornar sin llamarse a si misma a la funcion recursiva ya no se esta cumpliendo nunca.
Cita de: eferion en 5 Septiembre 2013, 13:11 PM
Es necesario que una función se llame de forma recursiva 40 veces ???
Lo mismo sería más lógico que no fuese recursiva y encerrar ese código en un bucle.
La función recursiva puede llamarse 40 veces, 100 o 2. Eso no depende de mi. Como ya he dicho se trata de hacer una estadística, y el llamar la función recursiva depende de números aleatorios. La primera llamada a la función recursiva es la que se hace 40 veces aprox antes de morir el programa. Vamos que antes de morir ha entrado y salido del "bucle de recursividad" unas 40 veces de forma satisfactoria. Ojala fuese tan fácil como cambiar la recursividad por un bucle! :)
Cita de: Eternal Idol en 5 Septiembre 2013, 13:30 PM
Listo, el problema esta ahi sin duda, lo mas probable es que la condicion que hacia retornar sin llamarse a si misma a la funcion recursiva ya no se esta cumpliendo nunca.
Pues parece que tienes razón porque al eliminar la recursividad de momento no me está dando fallos, pero la recursividad me es necesaria. Voy a probar a quitarle variables inútiles de esas que se quedan sueltas de cuando uno está construyendo el programa la primera vez para evitar que se desborde la pila. Esto que dices de la condición que hacia retornar no lo entiendo. ¿Puedes poner un ejemplo?
Muchas gracias por las respuestas, y un saludo a todos.
Ejemplo simple:
http://c.conclase.net/curso/?cap=024
/* Función recursiva para cálculo de factoriales */
int factorial(int n) {
if(n < 0) return 0;
else if(n > 1) return n*factorial(n-1); /* Recursividad */
return 1; /* Condicion de terminacion, n == 1 */
}
Cita de: pABL012 en 5 Septiembre 2013, 13:55 PM
La función recursiva puede llamarse 40 veces, 100 o 2. Eso no depende de mi. Como ya he dicho se trata de hacer una estadística, y el llamar la función recursiva depende de números aleatorios. La primera llamada a la función recursiva es la que se hace 40 veces aprox antes de morir el programa. Vamos que antes de morir ha entrado y salido del "bucle de recursividad" unas 40 veces de forma satisfactoria. Ojala fuese tan fácil como cambiar la recursividad por un bucle! :)
Pues parece que tienes razón porque al eliminar la recursividad de momento no me está dando fallos, pero la recursividad me es necesaria. Voy a probar a quitarle variables inútiles de esas que se quedan sueltas de cuando uno está construyendo el programa la primera vez para evitar que se desborde la pila. Esto que dices de la condición que hacia retornar no lo entiendo. ¿Puedes poner un ejemplo?
Muchas gracias por las respuestas, y un saludo a todos.
Aprovechando el ejemplo de Eternal....
/* Función recursiva para cálculo de factoriales */
int factorial(int n)
{
if(n < 0) return 0;
else if(n > 1) return n*factorial(n-1); /* Recursividad */
return 1; /* Condicion de terminacion, n == 1 */
}
/* Función sin recursividad para cálculo de factoriales */
int factorial(int n)
{
if(n < 0)
return 0;
int total = 1;
while ( n > 1 )
{
total *= n;
n--;
}
return total;
}
Definitivamente teníais razón. El problema era la recursividad. Al final lo he solucionado acotando el número de veces que puede llamarse a si misma la función.
Muchas gracias a todos por vuestra ayuda, y un saludo.
De nadas ::)
Todo algoritmo recursivo puede programarse como un algoritmo iterativo.
De todas formas, 40 me parecen muy pocas veces.