Título: Duda C++. Compila pero no corre. Publicado por: Gaspi en 15 Febrero 2015, 21:21 pm Hola, mi primer post en el foro, mil disculpas si rompo alguna regla, corríjanme si lo hago.
Miren, acabo de terminar un trabajo práctico para mi facultad, es programación básica, nada muy complicado, pero depende de éste que apruebe la materia. El problema radica en que el programa me compila de lo mejor, pero al ejecutarlo explota, no se porqué, estuve revisando y pienso que pude haber definido mal alguna lista, o hecho alguna mala comparación entre cadenas char, pero no sé. El código me parece muy extenso como para copiarlo y pegarlo, son alrededor de 500 líneas, pero copiaré lo que pueda estar mal. El trabajo se trata de hacer un fixture partiendo de un archivo de texto, que fue proporcionado junto con una funciones para facilitar el trabajo. Includes y estructuras: Código: #include <iostream> Acá están las funciones hechas por mí, no agrego las previas declaraciones, deben tener varios errores básicos, agradezco cualquier crítica y consejo que me ayude a mejorar. Main: Código: int main() { GenerarFixture (el objetivo de esta función es formar un fixture completo de l campeonato de fútbol, para eso usé la lista FIXTURE, y posteriormente la ordenada LISTANUEVA). La función generarPartido lo que hace es mediante un índice me devuelve los equipos que se enfrentarán: Código: void GenerarFixture(Equipo vectorequipos[], tipofixture *fixture, int &fechastotales, int &PartidosPorFecha, int &totalequipos) //Genera el fixture y además me devuelve algunos parámetros necesarios para saber tamaños Acá hay funciones que fueron necesarias para crear el fixture, la función leerEquipo fue proporcionada por el profesor, como dije antes, y lo que hace es leer el archivo sacando los parámetros allí indicados: Código: void LlenarVector(Equipo vectorequipos[], int &i) { //usando la función dada "leerequipo" lleno el vector y devuelvo el tamaño. Acá la parte de simular partido, simularPartido devuelve por referencia goleslocal y golesvisitante: Código: void menusimularpartido(tipofixture *fixture, tipofixture *listanueva,int fechastotales, int &PartidosPorFecha, posiciones vectortabla[], int &tamanio){ Lo final, acá hago la tabla de posiciones, ordenando un array y mostrando por pantalla los parámetros que indico allí. También acumulo 3 ptos. por partidos ganados. Código: void MostrarEquipo(tipofixture *listanueva,int PartidosPorFecha, int fechastotales){ Uso CodeBlocks, lo probé en una pc con XP, Vista y W7, pero en todas cuando corro me deja de funcionar, con el simple mensaje de "El programa ha dejado de funcionar". Muchísimas gracias a aquel que se haya gastado en leer todo esto, de verdad necesito una mano, cualquier pregunta voy a estar al tanto y a partir de hoy voy a intentar hacerme activo en el foro. Intenté ser los más claro posible al programar. Si a alguien le interesa las consignas del trabajo, acá están en un .pdf https://groups.google.com/group/ayedea/attach/9902d97dd397670f/TP_1.pdf?part=0.0.1&authuser=0 (https://groups.google.com/group/ayedea/attach/9902d97dd397670f/TP_1.pdf?part=0.0.1&authuser=0) Título: Re: Duda C++. Compila pero no corre. Publicado por: fary en 16 Febrero 2015, 08:05 am Creo que puede ser algún buffer que sea demasiado pequeño. También te falta el return de la función main.
saludos. Título: Re: Duda C++. Compila pero no corre. Publicado por: eferion en 16 Febrero 2015, 09:05 am Las funciones no deben terminar con ";"
Esto sucede con la copia que has puesto de "LlenarVector", por ejemplo. Estás programando en C++, no deberías usar los includes que acaben en ".h" Esas cabeceras son de C. Puedes cargar la cabecera propia de C++ poniendo el prefijo "C" y eliminando el ".h" ( #include <cmath> en vez de #include <math.h> ) Dado que estás programando en C++, sería más cómodo y seguro para tí usar la clase "string" en vez de "char*" para almacenar cadenas. Código
En C++ no hace falta usar "typedef" para declarar estructuras: Código
Los índices no los estás actualizando correctamente: Código
Fíjate que en la línea anterior estás actualizando "i", luego la línea marcada está modificando el índice del siguiente registro. Cuidado al inicializar los arreglos: Código
"fechastotales" es una variable. Esta forma de definir los arreglos no es estándar y puede darte problemas. Es más seguro crear un arreglo de tamaño fijo y más grande de lo necesario o recurrir a la memoria dinámica. La función AleatoriaFecha no funciona Si revisas el código, verás que "vec" únicamente va a contener un elemento SIEMPRE... en la función no hay ningún bucle. La función "crearlista" no funciona Código
En primer lugar, el nombre de la función no se corresponde con el funcionamiento teórico de la función, ya que no crea nada, en tal caso inicializa un puntero. En segundo lugar, esta función no hace ABSOLUTAMENTE NADA, "tipofixture", si bien es un puntero, es una variable local. Esto quiere decir que cualquier cambio que realices sobre el puntero en sí (ojo, no sobre la memoria "apuntada" ), es un cambio que va a desaparecer al salir el código de la función. Si tu idea es que el cambio del puntero se refleje fuera de la función tienes que usar un puntero doble: Código
Resumen Tu código tiene bastantes inconsistencias. Deberías revisarlo con más detenimiento. Ah si, y sería de agradecer que, para la siguiente ocasión, el código que facilitas pueda ser compilado... no es demasiado agradable tener que deducir el funcionamiento de tu programa únicamente viendo líneas de código. Un saludo Título: Re: Duda C++. Compila pero no corre. Publicado por: Gaspi en 16 Febrero 2015, 10:02 am Creo que puede ser algún buffer que sea demasiado pequeño. También te falta el return de la función main. saludos. Verdad lo del main, no lo había notado, quizá por eso no pasa del primer bucle. Muchas gracias. Las funciones no deben terminar con ";" Esto sucede con la copia que has puesto de "LlenarVector", por ejemplo. Estás programando en C++, no deberías usar los includes que acaben en ".h" Esas cabeceras son de C. Puedes cargar la cabecera propia de C++ poniendo el prefijo "C" y eliminando el ".h" ( #include <cmath> en vez de #include <math.h> ) Dado que estás programando en C++, sería más cómodo y seguro para tí usar la clase "string" en vez de "char*" para almacenar cadenas. En C++ no hace falta usar "typedef" para declarar estructuras: Los índices no los estás actualizcodecorrectamente: Fíjate que en la línea anterior estás actualizando "i", luego la línea marcada está modificando el índice del siguiente registro. Cuidado al inicializar los arreglos: "fechastotales" es una variable. Esta forma de definir los arreglos no es estándar y puede darte problemas. Es más seguro crear un arreglo de tamaño fijo y más grande de lcodeesario o recurrir amemoria dinámica. La función AleatoriaFecha no funciona Si revisas el código, verás que "vec" únicamente va a contener un elemento SIEMPRE... en la función no hay ningún bucle. La función "crearlista" no funciona En primer lugar, el nombre de la función no se corresponde con el funcionamiento teorico de la función, ya que no crea nada, en tal caso inicializa un puntero. En segundo lugar, esta función no hace ABSOLUTAMENTE NADA, "tipofixture", si bien es un puntero, es una variable local. Esto quiere decir que cualquier cambio que realices sobre el puntero en sí (ojo, no sobre la memoria "apuntada" ), es un cambio que va a desaparecer al salir el código de la función. Si tu idea es que el cambio del puntero se refleje fuera de la función tienes que usar un puntero doble: Resumen Tu código tiene bastantes inconsistencias. Deberías revisarlo con más detenimiento. Ah si, y sería de agradecer que, para la siguiente ocasión, el código que facilitas pueda ser compilado... no es demasiado agradable tener que deducir el funcionamiento de tu programa únicamente viendo líneas de código. Un saludo Muchísimas gracias por su tiempo leyendo todo y dándome útiles consejos. Paso a explicar algunas cosas: el Typedef lo uso de costumbre, es bueno saber que no hace falta. Las cadenas de tipo string no las tengo permitidas usar, el profesor nos dijo que eran sumamente inestables y que prefería que usemos char. El índice quería que empezara en 1, por eso el i++ previo. Es verdad lo de vec, debería haber definido 'w' en el ciclo de Generarfixture y pasarlo por referencia. Puede usted profundizar un poco lo que dijo al final sobre la función crearlista? Entiendo porqué es inútil, pero tenía entendido que las listas y los array siempre pasan por referencia. De nuevo, muchas gracias y tendré en cuenta la crítica final, mañana cuando pueda revisar todo, edito el tema subiendo la librería y las funciones faltantes. Que tenga un buen día Título: Re: Duda C++. Compila pero no corre. Publicado por: eferion en 16 Febrero 2015, 10:16 am Las cadenas de tipo string no las tengo permitidas usar, el profesor nos dijo que eran sumamente inestables y que prefería que usemos char. Me permito la licencia de decir públicamente que tu profesor no tiene ni la más mínima idea idea de programación. Las clases de la librería estándar están ahí por algo. Y su implementación es bastante eficiente y estable. Otra cosa es que, claro, al no tener mucha idea sobre programación orientada a objetos, prefiera que programéis lo más parecido a C posible... pero eso, como he dicho, no habla muy bien del nivel de tu profesor. A ver, tal y como lo entiendo, el profesor debería motivar vuestra curiosidad y abriros los ojos, no encasillaros y obligaros a programar de una forma que no será la que os encontréis luego en "el mundo real". El índice quería que empezara en 1, por eso el i++ previo. Imagínate que el arreglo admite dos elementos y estás rellenando el segundo. Al hacer "i++", i pasa a valer "2" y en la siguiente línea intenas escribir en el elemento con índice "2", es decir, estarías escribiendo en una posición de memoria no válida. pero tenía entendido que las listas y los array siempre pasan por referencia. Cuando usas un puntero como argumento, todo lo que modifiques que se refiera a la memoria apuntada por el puntero se verá reflejado fuera de la función... pero el puntero, como variable, es algo local, luego modificar la posición de memoria apuntada por el puntero es un cambio local y no se refleja fuera de la función. No se si me explico. Un saludo. Título: Re: Duda C++. Compila pero no corre. Publicado por: Gaspi en 16 Febrero 2015, 20:18 pm Cuando usas un puntero como argumento, todo lo que modifiques que se refiera a la memoria apuntada por el puntero se verá reflejado fuera de la función... pero el puntero, como variable, es algo local, luego modificar la posición de memoria apuntada por el puntero es un cambio local y no se refleja fuera de la función. No se si me explico. Mmm, si se explica. Debería cambiar el resto de las funciones en las que pasé una lista como parámetro? Me permito la licencia de decir públicamente que tu profesor no tiene ni la más mínima idea idea de programación. Las clases de la librería estándar están ahí por algo. Y su implementación es bastante eficiente y estable. Otra cosa es que, claro, al no tener mucha idea sobre programación orientada a objetos, prefiera que programéis lo más parecido a C posible... pero eso, como he dicho, no habla muy bien del nivel de tu profesor. La materia no cubre objetos, por eso las listas las hacemos de esa manera. Le discutiré eso pues mi profesor es graduado de la facultad más prestigiosa en ingeniería de mi país, donde estoy estudiando yo ahora, y sé que tiene sus razones para evitar que usemos los String. Imagínate que el arreglo admite dos elementos y estás rellenando el segundo. Al hacer "i++", i pasa a valer "2" y en la siguiente línea intenas escribir en el elemento con índice "2", es decir, estarías escribiendo en una posición de memoria no válida. Ahora capté lo que me quería decir, gracias, error solucionado. He dejado ya el link de descarga en Mediafire del trabajo entero y compilable. Título: Re: Duda C++. Compila pero no corre. Publicado por: Gaspi en 16 Febrero 2015, 22:14 pm http://www.mediafire.com/download/47n2996mw204vcs/Trabajo.zip
Título: Re: Duda C++. Compila pero no corre. Publicado por: eferion en 17 Febrero 2015, 08:13 am Debería cambiar el resto de las funciones en las que pasé una lista como parámetro? En aquellos casos en los que necesites modificar el valor del puntero (liberar memoria, modificar el tamaño de la memoria reservada, etc), SI. En estos casos es un imperativo para que los cambios se reflejen fuera de la función. En el resto de casos no es necesario y puede ser incluso contraproducente. Lo más sano es facilitar a cada función la cantidad mínima de datos necesaria. La materia no cubre objetos, por eso las listas las hacemos de esa manera. Le discutiré eso pues mi profesor es graduado de la facultad más prestigiosa en ingeniería de mi país, donde estoy estudiando yo ahora, y sé que tiene sus razones para evitar que usemos los String. Quizás, una de las pegas de la clase "string" es que no admite unicode... pero para eso está la clase "wstring". En cualquier caso, ambas clases forman parte del estándar... y aunque en la librería estándar existen bugs, no es motivo para no usarlos. Básicamente porque cualquier librería externa que tengas que usar (incluso las propias del sistema operativo) también están expuestas a fallos de programación y no por ello dejas de usarlas. Además, la librería estándar suele tener algoritmos altamente optimizados, por lo que suele ser la mejor opción para programas de uso general. Un saludo. Título: Re: Duda C++. Compila pero no corre. Publicado por: Gaspi en 17 Febrero 2015, 10:36 am En aquellos casos en los que necesites modificar el valor del puntero (liberar memoria, modificar el tamaño de la memoria reservada, etc), SI. En estos casos es un imperativo para que los cambios se reflejen fuera de la función. En el resto de casos no es necesario y puede ser incluso contraproducente. Lo más sano es facilitar a cada función la cantidad mínima de datos necesaria. Quizás, una de las pegas de la clase "string" es que no admite unicode... pero para eso está la clase "wstring". En cualquier caso, ambas clases forman parte del estándar... y aunque en la librería estándar existen bugs, no es motivo para no usarlos. Básicamente porque cualquier librería externa que tengas que usar (incluso las propias del sistema operativo) también están expuestas a fallos de programación y no por ello dejas de usarlas. Además, la librería estándar suele tener algoritmos altamente optimizados, por lo que suele ser la mejor opción para programas de uso general. Un saludo. Se agradece la ayuda nuevamente. Genial, ya hice los respectivos cambios y vi que cometí varios errores de lógica muy tontos como comparar solo con un =. Procedo a una depuración línea a línea a ver si consigo algo. Título: Re: Duda C++. Compila pero no corre. Publicado por: Gaspi en 20 Febrero 2015, 20:58 pm Pueden cerrar el tema, cree otro con un problema más específico.
|