Địa chỉ của i
sẽ không bao giờ thay đổi trong main()
, nhưng giá trị chứa trong đó sẽ. Bạn đang lấy tham chiếu của một biến cục bộ và sử dụng nó sau khi tham chiếu đó đã nằm ngoài phạm vi. (Cảnh báo ngôn ngữ hiển thị) Giá trị 6
đang ở trên ngăn xếp. Vì bạn không làm bất cứ điều gì với ngăn xếp sau khi bạn đặt 6
ở đó, tham chiếu đến nó sẽ vẫn chứa cùng một giá trị. Vì vậy, như những người khác đã nói, bạn đã may mắn.
Để xem như thế nào may mắn, hãy thử chạy mã này trong đó sử dụng ngăn xếp sau khi bạn gọi foo()
:
#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;
}
Khi tôi chạy này với post_foo()
cuộc gọi nhận xét ra, 6
vẫn còn trên stack và đầu ra là:
002CF6C8 = 6
002CF6C8 = 6
... nhưng khi tôi bỏ nhận xét cuộc gọi đến post_foo()
và chạy nó một lần nữa, 6
đã qua lâu rồi:
001FFD38 = 6
post_foo() = 310
001FFD38 = 258923464
Nguồn
2010-04-30 14:24:02
Bạn thật may mắn. Đừng làm thế. –
Bạn có thể thấy điều này hữu ích: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – letsc
Tôi tin rằng một số may mắn là trong thực tế rằng tôi là unaltered trong foo() (cho phép các trình biên dịch đặt trong văn bản hoặc một nơi nào đó tồn tại lâu thay vì ngăn xếp) – mho