elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  warning al pasar por referencia una variable local.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: warning al pasar por referencia una variable local.  (Leído 4,664 veces)
botella

Desconectado Desconectado

Mensajes: 80


Ver Perfil
warning al pasar por referencia una variable local.
« en: 7 Julio 2010, 16:01 pm »

Buenas, tengo un problema de concepto que no logro resolver de ninguna manera.

Doy un ejemplo rápido y abajo dejo el codigo completo de la clase racional que no es más que una clase para manejar números racionales.


En la sobrecarga de *,+, y - me encuentro que yo quiero devolver un valor que dentro de la función declaré como aux:

Racional& operator * ( Racional& r)
         {
                Racional aux;
                int deno,nume;
                deno= this->den * r.den;
                nume= this->num * r.num;
                aux.set_racional (nume,deno);              
                return aux;
        }

El programa funciona pero el compilador tira un warning:
 [Warning] reference to local variable `aux' returned

Y es lógico por que estoy pasando la dirección de memoria de un valor que desaparece con la función.
Pero funciona.
El tema es que si yo saco el &, para que la función en lugar de devolver una referencia devuelva la cosa en si misma:

Racional operator * ( Racional& r)
         {
                Racional aux;
                int deno,nume;
                deno= this->den * r.den;
                nume= this->num * r.num;
                aux.set_racional (nume,deno);              
                return aux;
        }


Esto también funciona, no tira el warning, pero tira el siguiente error al querer compilar:

 no match for 'operator=' in 'r3 = racional::operator*(Racional&)(((Racional&)(&r2)))'

Este error lo tira en la siguiente línea:
  r3 = r1 * r2;

Dejo el código completo funcionando, pero tirando los warnings.
Estoy laburando en dev++.
Alguien me dice si es que tengo que sobrecargar el operador = de alguna forma, o que tengo que hacer. Ya estuve buscando bastante en google y llegué a la conclusión de que el código está mal al pasar la referencia de un objeto que es una variable local, y quiero ver como solucionarlo.

saludos.

Código:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <math.h>

class Racional
{
    private:
        int num;
        int den;
    public:
        Racional (void):num(1),den(1){}
        Racional (int a, int b) {this->set_racional(a,b);}
        Racional (Racional& r){this->set_racional(r.num,r.den);}
        ~Racional () {};
        
        Racional& operator = ( Racional& r)
        {
            this->set_racional(r.num,r.den);
            return *this;
        }
        
        friend ostream& operator << (ostream& sal, Racional& r)
        {
            sal<<r.num<<"/"<<r.den<<" ";
            return sal;
        }
        
        float get_real()
        {
            return (float)num/(float)den;
        }
        
        void set_racional (int n, int d)
        {int i,;
            for ( i=12; i>0; i--)
            if (n%i==0 && d%i==0) {n=n/i;d=d/i;}
            if (d<0 && n<0) { d=d*(-1);n=n*(-1);};
            this->num=n;
            this->den=d;
        }
            
        /*
        Racional& operator + ( Racional& r)
        {
            int deno,nume;
            Racional aux;
            deno=this->den*r.den;
            nume= (   (deno/this->den) * this->num +  (deno/r.den)* r.num );
            aux.set_racional (nume,deno);
            return aux;
        }*/
        
        friend Racional& operator + (Racional& r, Racional& t)
        {
            int deno,nume;
            Racional aux;
            deno=t.den*r.den;
            nume= (   (deno/t.den) * t.num +  (deno/r.den)* r.num );
            aux.set_racional (nume,deno);
            return aux;
        }
            
            
            
        
        Racional& operator++ ()
        {
            int deno,nume;
            deno=this->den;
            nume=this->num+deno;
            this->set_racional (nume,deno);
            return *this;
        }
              
        int operator!= ( Racional& r)
        {
            return ( this->den!=r.den || this->num!=r.num);
        }
        
        Racional& operator - ( Racional& r)
        {
            int deno,nume;
            Racional aux;
            deno=this->den*r.den;
            nume= (   (deno/this->den) * this->num -  (deno/r.den)* r.num );
            aux.set_racional (nume,deno);
            return aux;
         }
         Racional& operator * ( Racional& r)
         {
                Racional aux;
                int deno,nume;
                deno= this->den * r.den;
                nume= this->num * r.num;
                aux.set_racional (nume,deno);              
                return aux;
        }
        
        Racional& operator + (int a)
        {
            Racional aux;
            int deno,nume;
            deno=this->den;
            nume=this->num + (a * deno);
            aux.set_racional (nume,deno);
            return aux;  
        }
friend       Racional& operator + (int a,Racional& r)
        {
            Racional aux;
            int deno,nume;
            deno=r.den;
            nume=r.num + (a * deno);
            aux.set_racional (nume,deno);
            return aux;  
        }
};

int main()
{
   Racional r1(1,1), r2(3,11), r3, r4 ,r5, r6;// r7(r1 + r2);
   r3 = r1 * r2;
   r4 = r3 + 5;
   r5 = 8 + r1;
   r1= r2 - r3;
   r6 = (r3 + r5);
   r4 = r3 + r5;
  
   cout << r1 << r2 << r3 << r4 << r5 <<endl;
   if (r5 != r6)
      cout << "Son distintos" << endl;
   getchar();
   return 0;
}


« Última modificación: 7 Julio 2010, 20:54 pm por botella » En línea

EvilGoblin


Desconectado Desconectado

Mensajes: 2.323


YO NO LA VOTE!


Ver Perfil
Re: warning al pasar por referencia una variable local.
« Respuesta #1 en: 7 Julio 2010, 18:58 pm »

usa los [ code][ /code]

tu codigo es verdaderamente complicado de entender xD
Pero en definitiva el "error" es que una vez que invocas a la funcion Racional, todo lo que invoques dentro de ella desaparece cuando la terminas

al pasarle valores de return, estas pasando aux (invocada dentro de Racional), asi que en programacion hay 2 alternativas... 1 dejar abierta la funcion (memoria reservada) para tener acceso , o liberar la memoria y pasar el puntero de esa informacion..

Opta por la 2da, osea te pasa el puntero de donde esta la informacion y libera la memoria cosa que te da el warning. si el programa se ejecutase por mucho tiempo ..

O va empezar a consumir cada vez mas memoria
o va a perder informacion.



PD: no pusiste si devueles un INT o CHAR a las funciones


En línea

Experimental Serial Lain [Linux User]
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: warning al pasar por referencia una variable local.
« Respuesta #2 en: 7 Julio 2010, 20:09 pm »

Recuerda que el puntero this no esta de adorno.

si declaras ClaseQueSea& operator# (ClaseQueSea &UnObjeto); y en algun punto llamas al operdor # de la clase ClaseQueSea ( a#b), estas generando una llamada a.operator#(b). Desreferencia el puntero this, para poder devolver una referencia al objeto a una vez realizada la llamada al operador, de esta forma podras concatenar sucesibas llamadas a funciones con un mismo objeto.

Por ejemplo, tienes una clase hora, com mimebros setHora, setMinuto y setSegundos. Si cada una de estas funciones retorna una referencia al objeto que las ha llamado podrass realizar llamadas del tipo:

Hora reloj;

reloj.setHora(3).setMinuto(14).setSetgundo(16);

¡Saludos!
En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
botella

Desconectado Desconectado

Mensajes: 80


Ver Perfil
Re: warning al pasar por referencia una variable local.
« Respuesta #3 en: 7 Julio 2010, 20:51 pm »

Gracias por las respuestas, pero no tal vez expresé mal la pregunta:

Simple:

Así el código compila y funciona y tira un warning.

Yo se que está mal, se por qué esta mal y lo quiero hacer bién.

Yo no quiero modificar el this, yo quiero dar un resultado independiente.
Es decir que no voy a modificar al objeto llamador.

Racional& operator + ( Racional& r)
Racional aux;

return aux; (ese aux es un objeto no una referencia) por eso me putea el compilador.

Entonces la forma correcta es:

Racional operator + (Racional& r)
//codigo..codigo
return aux;

De esta forma el compildor no tira los warnings, pero me putea cuando desde el main hago r5= r6 + r7.

Se entiende?


En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: warning al pasar por referencia una variable local.
« Respuesta #4 en: 7 Julio 2010, 21:15 pm »

¡Buenas!

Cuando en tiempos utilizaba C++, (lo usaba con devcpp), el echo de crear un variable temporal y querer utilizar una referencia a esta variable recien creada en una llamada a funcion no me daba mas que problemas. Y es lo que estas haciendo. Olvida lo que te he dicho sobre this, ya que en este caso el valor no queda almacenado en la variable llamadora al operador. Pueba a recibir como parametro en el operador de igualdad una variable de tipo Racional y no una referencia, y cuentanos que pasa.

¡Saludos!

Como trabajo en la uni hice una clase Complex, bastante completita. Si la encuentro (no se ni donde la tendre, porque de esto ya hace tres o cuatro años) te la paso, ya que tambien me encontre con todos esos "problemas".
« Última modificación: 7 Julio 2010, 21:18 pm por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
botella

Desconectado Desconectado

Mensajes: 80


Ver Perfil
Re: warning al pasar por referencia una variable local.
« Respuesta #5 en: 7 Julio 2010, 22:09 pm »

Ok, gracias.

Ya probé modificando el operator =, pero no dió resultado.

ya veremos.

ahora me voy a rendir el parcial

saludos.
En línea

carlitos_jajajajaja

Desconectado Desconectado

Mensajes: 30


Ver Perfil
Re: warning al pasar por referencia una variable local.
« Respuesta #6 en: 8 Julio 2010, 07:41 am »

Te explico lo que entiendo


Veras, esta es la historia de tu variable local cuando devuelves su referencia...

1)Cuando llamas a la funcion, esta reserva espacio para la memoria de la funcion (crea un stack segun recuerdo)

2)Tu variable local obtiene una direccion dentro del stack. Imaginate q esta direccion es 0x45D (El numero hexadecimal 45D, equivalente a 1117)

3)Tu funcion retorna la referencia a esta variable, o sea la posicion de memorioa numero 0x45d o 1117

4)La funcion termina de ejecutarse y se libera la pila. Enfatizo que se LIBERA, o sea que cualquier programa puede usarla a su gusto, pero no se elimina!!!! O sea que hasta que algun otro programa o proceso no se le asigne el byte Numero 45d, tu referencia seguira funcionando bien hasta que el sistema operativo asigne esa area a algun otro proceso y entonces todo comenzara a fallar :/


Sobre el operador =, es algo tambien un poco complejo:

El operador *, toma como argumento una variable de tipo racional y devuelve una variable del tipo Racional, hasta ahi vas bien.

este valor devuelto es bastante especial, porque ya saliste de la funcion, asi que la pila es liberada, pero todavia queda un dato que no podemos perder, el valor devuelto que probablemente asignaremos a otra variable. Es especial porque si te das cuenta es un tipo valor que no es parte de tu main (algo en teoria imposible porque solo los punteros y las referencias deberian poder accederse fuera de la pila; pero de esto se encarga el mismo c++ - probablemente volviendolo internamente una referencia - asi q todavia esta bien)

Entonces, viene el operador =, que toma como argumento ese tipo valor tan especial devuelto por el operador *. Normalmente cuando una funcion pide un valor por referencia, pero tu le pasas uno por valor, el c++ se encarga de referenciarla.

El problema es ahora que al parecer el c++ no tiene la capacidad de encargarse de referenciar este tipo, (que ya internamente es una referencia :/) por lo que ese valor devuelto solo podra ser pasado por valor al operador =, causando un error!!


Para arreglar este problema se me ocurren 2 opciones:

1) Crea otra version del operador =, pero pide los argumentos por valor en caso de que la variable no se pueda pasar por referencia como es tu caso:
Código
  1. Racional operator=(Racional r)//notece sin ningun & involucrado...
  2. {
  3.            this->set_racional(r.num,r.den);
  4.            return *this;
  5. }
  6.  

2)Utiliza c# jajajajaj


Bueno si no entiendes algode lo q dije (probable porque soy malo explicando) entonces pregunta lo q no entiendas.

Si quieres averiguar por tu cuenta como funcionan las referencias y las pilas de llamada a funcion, cheka estos links del curso de c++ mas copleto q he visto hasta ahora en la web:

http://www.zator.com/Cpp/E4_2_3.htm
http://www.zator.com/Cpp/E1_3_2.htm



Bye
En línea

Merodeo los foros, esperando el momento de decir algo inteligente...

Se necesita paciencia
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ayuda con variable de referencia
Java
тαптяα 4 2,319 Último mensaje 5 Octubre 2011, 19:32 pm
por тαптяα
Referencia de variable y objeto tras ingresarse como argumento
Java
Fabi0lo 2 2,644 Último mensaje 3 Abril 2012, 15:32 pm
por Fabi0lo
pasar por referencia un puntero
Programación C/C++
m@o_614 2 7,309 Último mensaje 18 Enero 2014, 18:13 pm
por rir3760
como referencia el codigo ensamblador a una variable (local) en memoria?
Programación General
MRx86 4 3,231 Último mensaje 22 Mayo 2017, 23:50 pm
por MRx86
Warning variable tipo double
Programación C/C++
antolinalvaro 0 1,210 Último mensaje 28 Julio 2018, 11:15 am
por antolinalvaro
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines