/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Acceso desde punteros y nulos

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
ragnar131



Registrado: 16 Nov 2007
Mensajes: 5

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com