| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
ragnar131
Registrado: 16 Nov 2007 Mensajes: 5
| Publicado: 17/11/2007 7:54 am | | | Título: Acceso desde punteros y nulos |
| Hola! Veréis, estoy realizando un programa de las torres de Hanoi en Xlib con gcc 4.2 y Kubuntu Gutsy Gibbon utilizando Kate y Konsole para su edición y compilación.
Sin entrar a poner todo el código, el problema es este:
Clase que define las estructuras:
| Código: | typedef struct{ int id; int x,y; int x_act,y_act; int anchura,altura; }ficha;
typedef struct{ int id; int x,y; //int bajo, medio, alto; //int iz,cn,dr; int anchura,altura; ficha *fila[3]; }pila; |
Clase que define unas funcionalidades:
| Código: | pila * donde (int x, pila *iz, pila *cn, pila *dr){ pila *res; ficha *prueba; if(x <= 210){ res = iz; }else if(x <= 420){ res = cn; }else if(x <= 630){ res = dr; } printf("Id de la pila escogida: %i\n",res->id); if(res->fila[2] != 0){ prueba = res->fila[2]; printf("Accedo a la ficha %i sin problemas\n", prueba->id); } } |
Y la función que utiliza este método...
| Código: | /* *Función que comprueba la posibilidad de traspasar una ficha de una pila a otra. *En caso posible, traslada dicha ficha. Además devolverá el valor 1 para advertir del éxito de la operación. *En caso contrario la modifica para que vuelva a su situación original. Devolverá un 0. */ int mover(pila *iz, pila *cn, pila *dr, ficha *f, int x, int y){ pila *origen = donde(f->x,iz,cn,dr); pila *destino = donde(x,iz,cn,dr); ficha *prueba; int res = 0; //Tenemos las pilas de origen y destino, y también la ficha a mover. //Veamos si es posible colocar la ficha en la pila destino. printf("Primera comparación\n"); prueba = destino->fila[2]; printf("A comparar\n"); if(prueba==0){ printf("Comparación se realizó con éxito\n"); //Puesto que la posición más baja está libre, la debjo colocar ahi if(borrar (origen, f)==0){ printf("fallo en el borrado\n"); } destino->fila[2] = f; res = 1; printf("Colocada ficha en la parte baja de pila %i\n",destino->id); }else if((destino->fila[2] != 0)&&(destino->fila[1]==0)){ if (destino->fila[2]->id > f->id){//Puedo colocarla if(borrar (origen, f)==0){ printf("fallo en el borrado\n"); } destino->fila[1] = f; res = 1; printf("Colocada ficha en la parte media de pila %i\n",destino->id); } }else if((destino->fila[1] != 0)&&(destino->fila[0]==0)){ if (destino->fila[1]->id > f->id){//Puedo colocarla if(borrar (origen, f)==0){ printf("fallo en el borrado\n"); } destino->fila[0] = f; res = 1; printf("Colocada ficha en la parte alta de pila %i\n",destino->id); } }//if return res; }//mover |
Al inicio de este último método, realiza de manera satisfactoria el acceso a un puntero (del array de punteros fila), y obtiene el valor de unos de sus campos (id) a través de la función donde. Poco después, intento acceder al puntero a ficha que hay en la pila destino (en principio, ya he accedido a esta pila en la función dónde y sé que en la posición 2 del array hay un nulo, ahora pondré el output en el que me apoyo para decir esto), y entonces en su ejecución obtengo esto: Fallo de segmentación (core dumped)
Aquí el output: Id de la pila escogida: 1 Accedo a la ficha 3 sin problemas Id de la pila escogida: 2 Primera comparación Fallo de segmentación (core dumped)
Como puede observarse, Accedo al id de ambas pilas sin problemas, en el caso de la pila 1, puedo acceder al id de una de las fichas que contiene. En la pila 2, como no tiene ficha (la posición apuntaría a nulo), cumple con la condición de nulos de la función dónde, y no se imprime nada. Si intento hacer una comprobación así en la función mover, me salta el fallo de segmentación. ¿Alguna idea?
Gracias por vuestro tiempo y atención, recibid un cordial saludo, Aitor. |
| | Volver arriba | |  | ragnar131
Registrado: 16 Nov 2007 Mensajes: 5
| Publicado: 17/11/2007 9:31 am | | | Título: |
| Esto no me lo esperaba, responderme yo a mí mismo. Le estaba dando vueltas (se vé que después de comer uno vé las cosas de otra forma), y si la idea era buena, el método dónde dice que devuelve un puntero, y no hay en el código ninguna sentencia return. Ha sido decir que devuelva el puntero y solucionado. Ahora, a seguir con el programa!
Veo que gcc no avisa de que no hay sentencia return (estaré demasiado acostumbrado al compilador de java).
El código final sería este:
| Código: | pila * donde (int x, pila *iz, pila *cn, pila *dr){ pila *res; ficha *prueba; if(x <= 210){ res = iz; }else if(x <= 420){ res = cn; }else if(x <= 630){ res = dr; } printf("Id de la pila escogida: %i\n",res->id); if(res->fila[2] != 0){ prueba = res->fila[2]; printf("Accedo a la ficha %i sin problemas\n", prueba->id); } return res; } |
En fin, por si a alguien le sirve. Al final los fallos más tontos son lo que más tiempo te consumen. Un saludo, y hasta otra. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 3770 Ubicación: Mexico
| Publicado: 17/11/2007 3:54 pm | | | Título: |
| Si compilas con las opciones de linea de comandos que te mencione en el otro tema gcc cuando se encuentra con una funcion que no retorna un valor (cuando deberia) emite el mensaje de advertencia:
| Código: | warning: control reaches end of non-void function |
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | | david_celta
Registrado: 02 Jun 2005 Mensajes: 95
| Publicado: 17/11/2007 5:32 pm | | | Título: |
| Sugerencia
Eso se podria evitar si al escribir la funcion, si esta devuelve un valor, lo escribimos previamente para que no "se nos olvide" colocarlo una vez hayamos terminado de escribirla
Por ejemplo si voy a definir una funcion Suma que devuelve la suma de dos valores la defino asi:
int Suma(int a, int b) { return resultado; }
y luego escribo el resto de codigo para la funcion, de esta manera se asegura que la instruccion return este presente. _________________ Rueda y rueda la vida, rueda y rueda el balón... y detras de la esperanza, palpita cada corazón. |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |