c++ - Can a local variable's memory be accessed outside its scope? -
i have following code.
int * foo() { int = 5; return &a; } int main() { int* p = foo(); cout << *p; *p = 8; cout << *p; }
and code running no runtime exceptions!
the output 58
how can be? isn't memory of local variable inaccessible outside function?
how can be? isn't memory of local variable inaccessible outside function?
you rent hotel room. put book in top drawer of bedside table , go sleep. check out next morning, "forget" give key. steal key!
a week later, return hotel, not check in, sneak old room stolen key, , in drawer. book still there. astonishing!
how can be? aren't contents of hotel room drawer inaccessible if haven't rented room?
well, scenario can happen in real world no problem. there no mysterious force causes book disappear when no longer authorized in room. nor there mysterious force prevents entering room stolen key.
the hotel management not required remove book. didn't make contract them said if leave stuff behind, they'll shred you. if illegally re-enter room stolen key back, hotel security staff not required catch sneaking in. didn't make contract them said "if try sneak room later, required stop me." rather, signed contract them said "i promise not sneak room later", contract you broke.
in situation anything can happen. book can there -- got lucky. else's book can there , yours in hotel's furnace. there right when come in, tearing book pieces. hotel have removed table , book entirely , replaced wardrobe. entire hotel torn down , replaced football stadium, , going die in explosion while sneaking around.
you don't know going happen; when checked out of hotel , stole key illegally use later, gave right live in predictable, safe world because you chose break rules of system.
c++ not safe language. cheerfully allow break rules of system. if try illegal , foolish going room you're not authorized in , rummaging through desk might not there anymore, c++ not going stop you. safer languages c++ solve problem restricting power -- having stricter control on keys, example.
update
holy goodness, answer getting lot of attention. (i'm not sure why -- considered "fun" little analogy, whatever.)
i thought might germane update bit few more technical thoughts.
compilers in business of generating code manages storage of data manipulated program. there lots of different ways of generating code manage memory, on time 2 basic techniques have become entrenched.
the first have sort of "long lived" storage area "lifetime" of each byte in storage -- is, period of time when validly associated program variable -- cannot predicted ahead of time. compiler generates calls "heap manager" knows how dynamically allocate storage when needed , reclaim when no longer needed.
the second have sort of "short lived" storage area lifetime of each byte in storage known, and, in particular, lifetimes of storages follow "nesting" pattern. is, allocation of longest-lived of short-lived variables strictly overlaps allocations of shorter-lived variables come after it.
local variables follow latter pattern; when method entered, local variables come alive. when method calls method, new method's local variables come alive. they'll dead before first method's local variables dead. relative order of beginnings , endings of lifetimes of storages associated local variables can worked out ahead of time.
for reason, local variables generated storage on "stack" data structure, because stack has property first thing pushed on going last thing popped off.
it's hotel decides rent out rooms sequentially, , can't check out until room number higher has checked out.
so let's think stack. in many operating systems 1 stack per thread , stack allocated fixed size. when call method, stuff pushed onto stack. if pass pointer stack out of method, original poster here, that's pointer middle of entirely valid million-byte memory block. in our analogy, check out of hotel; when do, checked out of highest-numbered occupied room. if no 1 else checks in after you, , go room illegally, stuff guaranteed still there in particular hotel.
we use stacks temporary stores because cheap , easy. implementation of c++ not required use stack storage of locals; use heap. doesn't, because make program slower.
an implementation of c++ not required leave garbage left on stack untouched can come later illegally; legal compiler generate code turns 0 in "room" vacated. doesn't because again, expensive.
an implementation of c++ not required ensure when stack logically shrinks, addresses used valid still mapped memory. implementation allowed tell operating system "we're done using page of stack now. until otherwise, issue exception destroys process if touches previously-valid stack page". again, implementations not because slow , unnecessary.
instead, implementations let make mistakes , away it. of time. until 1 day awful goes wrong , process explodes.
this problematic. there lot of rules , easy break them accidentally. have many times. , worse, problem surfaces when memory detected corrupt billions of nanoseconds after corruption happened, when hard figure out messed up.
more memory-safe languages solve problem restricting power. in "normal" c# there no way take address of local , return or store later. can take address of local, language cleverly designed impossible use after lifetime of local ends. in order take address of local , pass back, have put compiler in special "unsafe" mode, and put word "unsafe" in program, call attention fact doing dangerous breaking rules.
for further reading:
what if c# did allow returning references? coincidentally subject of today's blog post:
http://blogs.msdn.com/b/ericlippert/archive/2011/06/23/ref-returns-and-ref-locals.aspx
why use stacks manage memory? value types in c# stored on stack? how virtual memory work? , many more topics in how c# memory manager works. many of these articles germane c++ programmers:
https://blogs.msdn.microsoft.com/ericlippert/tag/memory-management/
Comments
Post a Comment