TransWikia.com

Conservar dato al pasar un puntero por referencia - C++

Stack Overflow en español Asked by finzeo on August 27, 2021

Estoy aprendiendo a pasar punteros por referencia a funciones.
Al cargar este código:

using namespace std;

void paso(int*&referencia)
{
    int* dir_cambio,m=2;
    dir_cambio=&m;
    referencia=dir_cambio;
    cout << "Dirección función: " << referencia << endl;
    cout << "Dato función: " << *referencia << endl;
}

int main()
{
    int *dir_entero,n=13;
    dir_entero=&n;
    cout << "Dirección inicial: " << dir_entero << endl;
    cout << "Dato inicial: " << *dir_entero << endl;
    paso(dir_entero);
    cout << "Dirección final: " << dir_entero << endl;
    cout << "Dato final: " << *dir_entero << endl;   
    return 0;
}

Me imprime:

Dirección inicial: 0x7ffd7f3b031c
Dato inicial: 13
Dirección función: 0x7ffd7f3b02ec
Dato función: 2
Dirección final: 0x7ffd7f3b02ec
Dato final: 32743```

Mi pregunta es: ¿Por qué no me aparece 2 como dato final?

La otra pregunta sería: ¿Cómo hago para poder usar el valor 2 en la función main usando el puntero dir_entero?

Edit:

El problema es el ámbito en el cual se trabaja. Quedó claro.
Sin embargo, hay algo que me desconcierta… Si coloco:

#include <iostream>
using namespace std;

void paso(int**referencia)
{```
    int *dir_cambio, m = 2;
    dir_cambio = &m;
    *referencia = dir_cambio;
}

int main()
{
    int *dir_entero,n=13;
    dir_entero=&n;
    cout  << *dir_entero << endl;
    paso(&dir_entero);
    cout << *dir_entero << endl;   
    return 0;
}

Me devuelve el 2, como espero.
Pero, con solo cambiar la antepenúltima línea a como se muestra ahora:

#include <iostream>
using namespace std;

void paso(int**referencia)
{
    int *dir_cambio, m = 2;
    dir_cambio = &m;
    *referencia = dir_cambio;
}

int main()
{
    int *dir_entero,n=13;
    dir_entero=&n;
    cout  << *dir_entero << endl;
    paso(&dir_entero);
    cout << "El dato final es: " <<  *dir_entero << endl;   
    return 0;
}

Ya vuelve a tener un comportamiento aleatorio como antes.
¿A qué se debe esto?

One Answer

¿ Por qué no me aparece 2 como dato final ?

Porque en tu función paso( ), estás asignando a referencia la dirección de tu variable automática m.

Las variables automáticas son aquellas cuyo tiempo de vida se limita al ámbito en el que se declaran. El compilador utiliza una determinada zona de memoria de forma temporal para crearlas, y dicha memoria es reutilizada para otras cosas cuando tu variable se destruye.

En tu caso, el ámbito es tu función paso( ). Es decir, m deja de existir al salir de tu función (el compilador reutiliza ese espacio para otras cosas), por lo que tu puntero modificado dir_entero queda apuntando a una dirección incorrecta. Mejor dicho, a una dirección que ya no contiene lo que tú esperas.

¿Cómo hago para poder usar el valor 2 en la función main usando el puntero dir_entero?

Lo tienes complicado. Tal y como lo has planteado, ya has visto el problema. No puedes usar una variable automática declarada en una función una vez que sales de ella.

Una posible solución es modificar un poco tu código, de forma que tu función paso( ) reciba 2 argumentos ... algo parecido a lo que hace std::swap( ):

void paso(int*&referencia, int&nuevo_valor )
{
    int* dir_cambio;
    dir_cambio=&nuevo_valor;
    referencia=dir_cambio;
    cout << "Dirección función: " << referencia << endl;
    cout << "Dato función: " << *referencia << endl;
}

int main()
{
    int *dir_entero,n=13, m=2;
    dir_entero=&n;
    cout << "Dirección inicial: " << dir_entero << endl;
    cout << "Dato inicial: " << *dir_entero << endl;
    paso(dir_entero, m);
    cout << "Dirección final: " << dir_entero << endl;
    cout << "Dato final: " << *dir_entero << endl;   
    return 0;
}

Correct answer by Trauma on August 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP