Die Adresse i
wird nie in main()
ändern, aber der darin enthaltene Wert wird. Sie nehmen die Referenz einer lokalen Variablen und verwenden sie, nachdem diese Referenz außerhalb des Gültigkeitsbereichs liegt. (Unpräzise Sprachwarnung) Der Wert 6
ist auf dem Stapel. Da Sie nichts mit dem Stack getan haben, nachdem Sie dort 6
eingegeben haben, enthält der Verweis darauf immer noch denselben Wert. Wie andere gesagt haben, haben Sie Glück gehabt.
Um zu sehen, wie glücklich, versuchen Sie diesen Code ausgeführt wird, die den Stapel verwendet, nachdem Sie foo()
nennen:
#include <iostream>
#include <ctime>
#include <numeric>
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;
}
Wenn ich dies mit dem post_foo()
Anruf lief auf Kommentar, 6
war noch auf dem Stapel und dem Ausgang war:
002CF6C8 = 6
002CF6C8 = 6
... aber wenn ich den Anruf zu post_foo()
und lief wieder es unkommentiert wurde 6
lange vorbei:
001FFD38 = 6
post_foo() = 310
001FFD38 = 258923464
Sie haben nur Glück. Tu es nicht. –
Sie können dies nützlich finden: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – letsc
Ich glaube, etwas Glück ist in der Tatsache, dass ich bin unverändert in foo() (was Compilern erlaubt, in Text oder irgendwo langlebig anstelle von Stack zu platzieren) – mho