Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Duda sobre c++. Se pierden datos al salir de un while.

Estas en el tema de Duda sobre c++. Se pierden datos al salir de un while. en el foro de C/C++ en Foros del Web. Hola familia. Estoy desarrollando un programa en c++ y me ocurre algo muy raro. Os dejo el código: arbol * dePostaArbol(string cadena){ string buf; pilaArbol ...
  #1 (permalink)  
Antiguo 14/03/2013, 05:33
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Busqueda Duda sobre c++. Se pierden datos al salir de un while.

Hola familia.
Estoy desarrollando un programa en c++ y me ocurre algo muy raro. Os dejo el código:

arbol * dePostaArbol(string cadena){
string buf;
pilaArbol stack_tree= pilaArbol();

arbol * salida = NULL;
arbol* pab;
stringstream ss (cadena);
while (ss >> buf){
if (buf.compare("DIA")==0){//OPERADOR DIAMANTE
insertarOperadorEnPila(stack_tree,-1);//DIA == -1
}else if (buf.compare("BOX")==0){//OPEEADOR CAJA
insertarOperadorEnPila(stack_tree,-2);//BOX == -2
}else if (buf.compare("NOT")==0){//NEGACION
insertarOperadorEnPila(stack_tree,-3);//DIA == -3
}else if (buf.compare("AND")==0){//OPERADOR AND1
insertarOperadorEnPila(stack_tree,-4);//DIA == -4
}else if (buf.compare("OR")==0){//OPERADOR OR
insertarOperadorEnPila(stack_tree,-5);//DIA == -5
}else if (buf.compare("IMPLIES")==0){//IMPLICACION
insertarOperadorEnPila(stack_tree,-6);//DIA == -6
}else{//OPERANDO...

int valorOperador;
pab= new arbol();
valorOperador=codifica(buf);
pab->setValor(valorOperador);
stack_tree.Push(pab);
}
pPila=&stack_tree;
}
if (stack_tree.isEmpty()){
cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;

stack_tree.destruir();
exit (-1);

}else{
salida=stack_tree.Pop();
if(stack_tree.isEmpty()){
stack_tree.destruir();
return salida;
}else{
cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
exit (-1);
stack_tree.destruir();
}
}
}


El problema está en que cuando va a salir del bucle while, se pierden todos los datos de la pila. Justo antes de salir del while la pila contiene lo que debe, es decir, que el programa funciona bien, pero pierde los datos al salir del while... Y no se a que se debe... Tal vez sea algo de c++ que no sepa.... Gracias a todos de antemano.
  #2 (permalink)  
Antiguo 14/03/2013, 05:49
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 11 meses
Puntos: 606
Respuesta: Duda sobre c++. Se pierden datos al salir de un while.

Cuando dices "la pila" a que variable te refieres? Si identas el codigo con las etiquetas "HIGHLIGHT" ayudará a entenderlo.
__________________
Aviso: No se resuelven dudas por MP!
  #3 (permalink)  
Antiguo 14/03/2013, 05:55
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Duda sobre c++. Se pierden datos al salir de un while.

La variable a la que me refiero a a stack_tree.

Creo que es esto a lo que te refieres que haga.
Código:
Código C++:
Ver original
  1. arbol * dePostaArbol(string cadena){
  2.         string buf; // Have a buffer string
  3.         pilaArbol stack_tree= pilaArbol();
  4.         pilaArbol * pPila;
  5.         arbol * salida = NULL; //La formula en postfija
  6.         arbol* pab;
  7.         stringstream ss (cadena); // Inserta la cadena en un stream que separa tokens por " "
  8.         while (ss >> buf){
  9.             if (buf.compare("DIA")==0){//OPERADOR DIAMANTE
  10.                 insertarOperadorEnPila(stack_tree,-1);//DIA == -1
  11.             }else if (buf.compare("BOX")==0){//OPEEADOR CAJA
  12.                 insertarOperadorEnPila(stack_tree,-2);//BOX == -2
  13.             }else if (buf.compare("NOT")==0){//NEGACION
  14.                 insertarOperadorEnPila(stack_tree,-3);//DIA == -3
  15.             }else if (buf.compare("AND")==0){//OPERADOR AND1
  16.                 insertarOperadorEnPila(stack_tree,-4);//DIA == -4
  17.             }else if (buf.compare("OR")==0){//OPERADOR OR
  18.                 insertarOperadorEnPila(stack_tree,-5);//DIA == -5
  19.             }else if (buf.compare("IMPLIES")==0){//IMPLICACION
  20.                 insertarOperadorEnPila(stack_tree,-6);//DIA == -6
  21.             }else{//OPERANDO...
  22.                
  23.                 int valorOperador;
  24.                 pab= new arbol();
  25.                 valorOperador=codifica(buf);
  26.                 pab->setValor(valorOperador);
  27.                 stack_tree.Push(pab);
  28.             }
  29.             pPila=&stack_tree;
  30.         }
  31.         if (stack_tree.isEmpty()){
  32.             cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
  33.             exit (-1);
  34.             stack_tree.destruir();
  35.         }else{
  36.             salida=stack_tree.Pop();
  37.             if(stack_tree.isEmpty()){
  38.                 stack_tree.destruir();
  39.                 return salida;
  40.             }else{
  41.                 cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
  42.                 exit (-1);
  43.                 stack_tree.destruir();
  44.             }
  45.         }
  46.     }

El problema está en que al salir del bucle While, todas las referencias que hay en la pila se pierden. He probado la clase pilaArbol y funciona. No se que es lo que pasa. Es decir, cuando la condición del bucle no se cumple, sale del bucle y los punteros pierden todas las referencias, pero mientras se cumple la condición, la pila no pierde las referencias... Es muy raro, o me lo parece a mi?.

Última edición por efdarcy09; 14/03/2013 a las 06:01
  #4 (permalink)  
Antiguo 14/03/2013, 06:45
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Duda sobre c++. Se pierden datos al salir de un while.

Creo que ya he encontrado el problema. Pero no se como solucionarlo...
El problemas es que cuando llamo al void

Código C++:
Ver original
  1. void insertarOperadorEnPila(pilaArbol p, int operador){
  2.         if(operador<-4){
  3.             arbol* a1= new arbol();
  4.             arbol* a2 = new arbol();
  5.             arbol* res;
  6.             arbol aux= arbol();
  7.             a2=p.Pop();
  8.             a1=p.Pop();
  9.             if ((a1==NULL) || (a2=NULL)){
  10.                 cout<<"Error, faltan elementos en la pila"<<endl;
  11.                 exit (-1);
  12.             }
  13.             aux.setValor(operador);
  14.             aux.insertarIzq(a2);
  15.             aux.insertarDer(a1);
  16.             res=&aux;
  17.             p.Push(res);
  18.         }else{
  19.             arbol* a1;
  20.             arbol* res;
  21.             arbol aux= arbol();
  22.             a1=p.Pop();
  23.             if (a1==NULL){
  24.                 cout<<"Error, faltan elementos en la pila"<<endl;
  25.                 exit (-1);
  26.             }
  27.  
  28.             aux.setValor(operador);
  29.             aux.insertarIzq(a1);
  30.             res=&aux;
  31.             p.Push(res);
  32.         }
  33.     }
Creo dos arboles que, al salir del While, desaparecen... No se como solucionarlo sin hacer un procedimiento a parte.... Alguna idea??.
  #5 (permalink)  
Antiguo 14/03/2013, 12:12
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 5 meses
Puntos: 28
Respuesta: Duda sobre c++. Se pierden datos al salir de un while.

Vamos a ver, hay que diferencia entre memoria estática y memoria dinámica.

La memoría estática es la que se coje internamente de la pila, cada vez que declaramos una variable/objeto estamos cogiendola de la pila:

Código C++:
Ver original
  1. int cosa;
  2. arbol font;
  3.  
  4. //...

Estas variables, son variables de ambito. Nacen con un ambito de llaves y mueren cuando finaliza este.

Por ejemplo, si se crea durante un if:

Código C++:
Ver original
  1. if (calabaza == true)
  2. {
  3.     int resultado; // variable estática
  4.    //...
  5. } // muerte de la variable resultado

La memoria dinámica es la que se crea con new y dura hasta que se llama a delete.

Volviendo al ejemplo actual:

Código C++:
Ver original
  1. arbol * dePostaArbol(string cadena){
  2.         string buf; // Have a buffer string
  3.         pilaArbol stack_tree= pilaArbol();
  4.         pilaArbol * pPila;
  5.         arbol * salida = NULL; //La formula en postfija
  6.         arbol* pab;
  7.         stringstream ss (cadena); // Inserta la cadena en un stream que separa tokens por " "
  8.         while (ss >> buf){
  9.             if (buf.compare("DIA")==0){//OPERADOR DIAMANTE
  10.                 insertarOperadorEnPila(stack_tree,-1);//DIA == -1
  11.             }else if (buf.compare("BOX")==0){//OPEEADOR CAJA
  12.                 insertarOperadorEnPila(stack_tree,-2);//BOX == -2
  13.             }else if (buf.compare("NOT")==0){//NEGACION
  14.                 insertarOperadorEnPila(stack_tree,-3);//DIA == -3
  15.             }else if (buf.compare("AND")==0){//OPERADOR AND1
  16.                 insertarOperadorEnPila(stack_tree,-4);//DIA == -4
  17.             }else if (buf.compare("OR")==0){//OPERADOR OR
  18.                 insertarOperadorEnPila(stack_tree,-5);//DIA == -5
  19.             }else if (buf.compare("IMPLIES")==0){//IMPLICACION
  20.                 insertarOperadorEnPila(stack_tree,-6);//DIA == -6
  21.             }else{//OPERANDO...
  22.                
  23.                 int valorOperador;
  24.                 pab= new arbol();
  25.                 valorOperador=codifica(buf);
  26.                 pab->setValor(valorOperador);
  27.                 stack_tree.Push(pab);
  28.             }
  29.             pPila=&stack_tree;
  30.         }
  31.         if (stack_tree.isEmpty()){
  32.             cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
  33.             exit (-1);
  34.             stack_tree.destruir();
  35.         }else{
  36.             salida=stack_tree.Pop();
  37.             if(stack_tree.isEmpty()){
  38.                 stack_tree.destruir();
  39.                 return salida;
  40.             }else{
  41.                 cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
  42.                 exit (-1);
  43.                 stack_tree.destruir();
  44.             }
  45.         }
  46.     }

El error está cuando asignamos el puntero pPila a la variable estática stack_tree. No es que los punteros pierdan la referencia, esque cuando salimos de la función se borra stack_tree y el puntero pPila apunta ahora, a una memoria vacía.

La solución consiste en poner stack_tree como memoria dinámica:

Código C++:
Ver original
  1. int cosa;
  2. arbol font;
  3.  
  4. //...

Estas variables, son variables de ambito. Nacen con un ambito de llaves y mueren cuando finaliza este.

Por ejemplo, si se crea durante un if:

Código C++:
Ver original
  1. if (calabaza == true)
  2. {
  3.     int resultado; // variable estática
  4.    //...
  5. } // muerte de la variable resultado

La memoria dinámica es la que se crea con new y dura hasta que se llama a delete.

Volviendo al ejemplo actual:

Código C++:
Ver original
  1. arbol * dePostaArbol(string cadena){
  2.         string buf; // Have a buffer string
  3.         pilaArbol* stack_tree= new arbol;
  4.         *stack_tree = pilaArbol();
  5.         pilaArbol * pPila;
  6.         arbol * salida = NULL; //La formula en postfija
  7.         arbol* pab;
  8.         stringstream ss (cadena); // Inserta la cadena en un stream que separa tokens por " "
  9.         while (ss >> buf){
  10.             if (buf.compare("DIA")==0){//OPERADOR DIAMANTE
  11.                 insertarOperadorEnPila(*stack_tree,-1);//DIA == -1
  12.             }else if (buf.compare("BOX")==0){//OPEEADOR CAJA
  13.                 insertarOperadorEnPila(*stack_tree,-2);//BOX == -2
  14.             }else if (buf.compare("NOT")==0){//NEGACION
  15.                 insertarOperadorEnPila(*stack_tree,-3);//DIA == -3
  16.             }else if (buf.compare("AND")==0){//OPERADOR AND1
  17.                 insertarOperadorEnPila(*stack_tree,-4);//DIA == -4
  18.             }else if (buf.compare("OR")==0){//OPERADOR OR
  19.                 insertarOperadorEnPila(*stack_tree,-5);//DIA == -5
  20.             }else if (buf.compare("IMPLIES")==0){//IMPLICACION
  21.                 insertarOperadorEnPila(*stack_tree,-6);//DIA == -6
  22.             }else{//OPERANDO...
  23.                
  24.                 int valorOperador;
  25.                 pab= new arbol();
  26.                 valorOperador=codifica(buf);
  27.                 pab->setValor(valorOperador);
  28.                 stack_tree->Push(pab);
  29.             }
  30.             pPila=stack_tree;
  31.         }
  32.         if (stack_tree->isEmpty()){
  33.             cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
  34.          
  35.             stack_tree->destruir();
  36.                 exit (-1);
  37.         }else{
  38.             salida=stack_tree->Pop();
  39.             if(stack_tree->isEmpty()){
  40.                 stack_tree->destruir();
  41.                 return salida;
  42.             }else{
  43.                 cout<<"Error: El algoritmo de conversion de postfija a arbol ha fallado..."<<endl;
  44.              
  45.                 stack_tree->destruir();
  46.    exit (-1);
  47.             }
  48.         }
  49.     }

Notesé:

- Que para acceder al contenido de stack_tree usamos * (porque es un puntero).
- Que para llamar a los método de stack_tree usamos el operador -> (porque estamos usando puntero).
  #6 (permalink)  
Antiguo 15/03/2013, 05:04
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Duda sobre c++. Se pierden datos al salir de un while.

Mil gracias. Todo solucionado... C++ y los punteros, Que divertido!! :|.

Etiquetas: funcion, int, programa, salir, string
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:04.