Devolver una referencia a una variable local o temporal

Mira el código a continuación. Sé que no devuelve la dirección de la variable local, pero ¿por qué funciona y asigna la variable i en main () a ‘6’? ¿Cómo solo devuelve el valor si la variable se eliminó de la memoria de la stack?

 #include  int& foo() { int i = 6; std::cout << &i << std::endl; //Prints the address of i before return return i; } int main() { int i = foo(); std::cout << i << std::endl; //Prints the value std::cout << &i << std::endl; //Prints the address of i after return } 

Tuviste suerte. Al regresar de la función, no se limpia inmediatamente el marco de stack que acaba de salir.

Por cierto, ¿cómo confirmaste que obtuviste un 6? La expresión std::cout << &i ... imprime la dirección de i , no su valor.

Debe ser algo que hace tu comstackdor.

http://www.learncpp.com/cpp-tutorial/74a-returning-values-by-value-reference-and-address/

Confirma que su ejemplo eliminará la referencia de la memoria de la stack.

Devolver referencia o puntero a una variable local es un comportamiento indefinido. Comportamiento no definido significa que el estándar deja la decisión al comstackdor. Eso significa que el comportamiento indefinido a veces funciona bien y otras veces no .

La dirección de i nunca cambiará en main() , pero sí lo hará el valor que contiene. Está tomando la referencia de una variable local y usándola después de que la referencia haya caído fuera del scope. (Advertencia de lenguaje impreciso) El valor 6 está en la stack. Como no hiciste nada con la stack después de poner 6 allí, la referencia a ella todavía contendrá el mismo valor. Entonces, como otros han dicho, tuvieron suerte.

Para ver qué suerte, intente ejecutar este código que usa la stack después de llamar a foo() :

 #include  #include  #include  int& foo() { int i = 6; std::cout << &i << " = " << i << std::endl; //Prints the address of i before return return i; } long post_foo(int f) { srand((unsigned)time(0)); long vals[10] = {0}; size_t num_vals = sizeof(vals)/sizeof(vals[0]); for( size_t i = 0; i < num_vals; ++i ) { int r = (rand()%2)+1; vals[i] = (i+f)*r; } long accum = std::accumulate(vals, &vals[num_vals], 0); return accum * 2; } int main() { int &i = foo(); // std::cout << "post_foo() = " << post_foo(i) << std::endl; std::cout << &i << " = " << i << std::endl; } 

Cuando ejecuté esto con la llamada post_foo() comentada, 6 todavía estaba en la stack y el resultado fue:

 002CF6C8 = 6 002CF6C8 = 6 

... pero cuando no comenté la llamada a post_foo() y la post_foo() a post_foo() , 6 estaba:

 001FFD38 = 6 post_foo() = 310 001FFD38 = 258923464 

Mientras que su función devuelve un número entero por referencia, se asigna inmediatamente a la variable local ‘i’ en main (). Eso significa que la memoria de stack asignada para foo () debe persistir el tiempo suficiente para la asignación de retorno. Si bien es mala forma, esto generalmente funciona. Si hubiera tratado de mantener una referencia

 int &i = foo(); 

sería mucho más probable que fallara.