Hãy xem một ví dụ nơi bạn có thể truy cập vào vùng nhớ của một biến cục bộ bên ngoài phạm vi của nó.
Ví dụ
#include <iostream>
int* foo() {
int x = 3;
return &x;
}
int main() {
int* address = foo();
std::cout << *address;
*address = 12;
std::cout << *address;
}
Đầu ra
Chương trình có thể cho kết quả sau:
3 12
Như đã đề cập, mã này có thể chạy được. Chúng ta chỉ đang đọc và ghi vào vùng nhớ trước đây là địa chỉ của x. Trong main, bạn đang ở ngoài phạm vi của foo, con trỏ trỏ đến một vùng nhớ ngẫu nhiên. Trong ví dụ trên, vùng nhớ đó vẫn tồn tại và chưa bị ghi đè. Bạn không vi phạm quyền truy cập bộ nhớ (không truy cập vào bộ nhớ của tiến trình khác), và giá trị 3 vẫn còn đó.
Trong chương trình thực tế, vùng nhớ đó có thể được tái sử dụng gần như ngay lập tức, và việc truy cập như vậy sẽ làm hỏng dữ liệu. Lỗi truy cập bộ nhớ dạng này rất khó phát hiện và khắc phục.
Khi trả về từ foo, chương trình thông báo cho hệ điều hành rằng bộ nhớ của x không còn được sử dụng và có thể gán cho mục đích khác. Nếu bạn may mắn và nó chưa được gán lại, đồng thời hệ điều hành không phát hiện việc bạn truy cập lại, thì bạn có thể "lướt qua" được.