@@ -217,12 +217,12 @@ on the heap. The actual value of the box is a structure which has a pointer to
217217it allocates some memory for the heap, and puts ` 5 ` there. The memory now looks
218218like this:
219219
220- | Address | Name | Value |
221- | -----------------| ------| ----------------|
222- | 2<sup >30</sup > | | 5 |
223- | ... | ... | ... |
224- | 1 | y | 42 |
225- | 0 | x | 2<sup >30</sup > |
220+ | Address | Name | Value |
221+ | -----------------| ------| ------------------ |
222+ | 2<sup >30</sup > | | 5 |
223+ | ... | ... | ... |
224+ | 1 | y | 42 |
225+ | 0 | x | → 2<sup >30</sup > |
226226
227227We have 2<sup >30</sup > in our hypothetical computer with 1GB of RAM. And since
228228our stack grows from zero, the easiest place to allocate memory is from the
@@ -242,17 +242,17 @@ freed in any order, it can end up with ‘holes’. Here’s a diagram of the me
242242layout of a program which has been running for a while now:
243243
244244
245- | Address | Name | Value |
246- | ----------------------| ------| ----------------------|
247- | 2<sup >30</sup > | | 5 |
248- | (2<sup >30</sup >) - 1 | | |
249- | (2<sup >30</sup >) - 2 | | |
250- | (2<sup >30</sup >) - 3 | | 42 |
251- | ... | ... | ... |
252- | 3 | y | (2<sup >30</sup >) - 3 |
253- | 2 | y | 42 |
254- | 1 | y | 42 |
255- | 0 | x | 2<sup >30</sup > |
245+ | Address | Name | Value |
246+ | ----------------------| ------| ------------------------ |
247+ | 2<sup >30</sup > | | 5 |
248+ | (2<sup >30</sup >) - 1 | | |
249+ | (2<sup >30</sup >) - 2 | | |
250+ | (2<sup >30</sup >) - 3 | | 42 |
251+ | ... | ... | ... |
252+ | 3 | y | → (2<sup >30</sup >) - 3 |
253+ | 2 | y | 42 |
254+ | 1 | y | 42 |
255+ | 0 | x | → 2<sup >30</sup > |
256256
257257In this case, we’ve allocated four things on the heap, but deallocated two of
258258them. There’s a gap between 2<sup >30</sup > and (2<sup >30</sup >) - 3 which isn’t
@@ -304,22 +304,22 @@ fn main() {
304304
305305When we enter ` main() ` , memory looks like this:
306306
307- | Address | Name | Value |
308- | ---------| ------| -------|
309- | 1 | y | 0 |
310- | 0 | x | 5 |
307+ | Address | Name | Value |
308+ | ---------| ------| -------- |
309+ | 1 | y | → 0 |
310+ | 0 | x | 5 |
311311
312312` x ` is a plain old ` 5 ` , and ` y ` is a reference to ` x ` . So its value is the
313313memory location that ` x ` lives at, which in this case is ` 0 ` .
314314
315315What about when we call ` foo() ` , passing ` y ` as an argument?
316316
317- | Address | Name | Value |
318- | ---------| ------| -------|
319- | 3 | z | 42 |
320- | 2 | i | 0 |
321- | 1 | y | 0 |
322- | 0 | x | 5 |
317+ | Address | Name | Value |
318+ | ---------| ------| -------- |
319+ | 3 | z | 42 |
320+ | 2 | i | → 0 |
321+ | 1 | y | → 0 |
322+ | 0 | x | 5 |
323323
324324Stack frames aren’t just for local bindings, they’re for arguments too. So in
325325this case, we need to have both ` i ` , our argument, and ` z ` , our local variable
@@ -366,152 +366,152 @@ fn main() {
366366
367367First, we call ` main() ` :
368368
369- | Address | Name | Value |
370- | -----------------| ------| ----------------|
371- | 2<sup >30</sup > | | 20 |
372- | ... | ... | ... |
373- | 2 | j | 0 |
374- | 1 | i | 2<sup >30</sup > |
375- | 0 | h | 3 |
369+ | Address | Name | Value |
370+ | -----------------| ------| ------------------ |
371+ | 2<sup >30</sup > | | 20 |
372+ | ... | ... | ... |
373+ | 2 | j | → 0 |
374+ | 1 | i | → 2<sup >30</sup > |
375+ | 0 | h | 3 |
376376
377377We allocate memory for ` j ` , ` i ` , and ` h ` . ` i ` is on the heap, and so has a
378378value pointing there.
379379
380380Next, at the end of ` main() ` , ` foo() ` gets called:
381381
382- | Address | Name | Value |
383- | -----------------| ------| ----------------|
384- | 2<sup >30</sup > | | 20 |
385- | ... | ... | ... |
386- | 5 | z | 4 |
387- | 4 | y | 10 |
388- | 3 | x | 0 |
389- | 2 | j | 0 |
390- | 1 | i | 2<sup >30</sup > |
391- | 0 | h | 3 |
382+ | Address | Name | Value |
383+ | -----------------| ------| ----------------- |
384+ | 2<sup >30</sup > | | 20 |
385+ | ... | ... | ... |
386+ | 5 | z | → 4 |
387+ | 4 | y | 10 |
388+ | 3 | x | → 0 |
389+ | 2 | j | → 0 |
390+ | 1 | i | → 2<sup >30</sup >|
391+ | 0 | h | 3 |
392392
393393Space gets allocated for ` x ` , ` y ` , and ` z ` . The argument ` x ` has the same value
394394as ` j ` , since that’s what we passed it in. It’s a pointer to the ` 0 ` address,
395395since ` j ` points at ` h ` .
396396
397397Next, ` foo() ` calls ` baz() ` , passing ` z ` :
398398
399- | Address | Name | Value |
400- | -----------------| ------| ----------------|
401- | 2<sup >30</sup > | | 20 |
402- | ... | ... | ... |
403- | 7 | g | 100 |
404- | 6 | f | 4 |
405- | 5 | z | 4 |
406- | 4 | y | 10 |
407- | 3 | x | 0 |
408- | 2 | j | 0 |
409- | 1 | i | 2<sup >30</sup > |
410- | 0 | h | 3 |
399+ | Address | Name | Value |
400+ | -----------------| ------| ------------------ |
401+ | 2<sup >30</sup > | | 20 |
402+ | ... | ... | ... |
403+ | 7 | g | 100 |
404+ | 6 | f | → 4 |
405+ | 5 | z | → 4 |
406+ | 4 | y | 10 |
407+ | 3 | x | → 0 |
408+ | 2 | j | → 0 |
409+ | 1 | i | → 2<sup >30</sup > |
410+ | 0 | h | 3 |
411411
412412We’ve allocated memory for ` f ` and ` g ` . ` baz() ` is very short, so when it’s
413413over, we get rid of its stack frame:
414414
415- | Address | Name | Value |
416- | -----------------| ------| ----------------|
417- | 2<sup >30</sup > | | 20 |
418- | ... | ... | ... |
419- | 5 | z | 4 |
420- | 4 | y | 10 |
421- | 3 | x | 0 |
422- | 2 | j | 0 |
423- | 1 | i | 2<sup >30</sup > |
424- | 0 | h | 3 |
415+ | Address | Name | Value |
416+ | -----------------| ------| ------------------ |
417+ | 2<sup >30</sup > | | 20 |
418+ | ... | ... | ... |
419+ | 5 | z | → 4 |
420+ | 4 | y | 10 |
421+ | 3 | x | → 0 |
422+ | 2 | j | → 0 |
423+ | 1 | i | → 2<sup >30</sup > |
424+ | 0 | h | 3 |
425425
426426Next, ` foo() ` calls ` bar() ` with ` x ` and ` z ` :
427427
428- | Address | Name | Value |
429- | ----------------------| ------| ----------------------|
430- | 2<sup >30</sup > | | 20 |
431- | (2<sup >30</sup >) - 1 | | 5 |
432- | ... | ... | ... |
433- | 10 | e | 9 |
434- | 9 | d | (2<sup >30</sup >) - 1 |
435- | 8 | c | 5 |
436- | 7 | b | 4 |
437- | 6 | a | 0 |
438- | 5 | z | 4 |
439- | 4 | y | 10 |
440- | 3 | x | 0 |
441- | 2 | j | 0 |
442- | 1 | i | 2<sup >30</sup > |
443- | 0 | h | 3 |
428+ | Address | Name | Value |
429+ | ----------------------| ------| ------------------------ |
430+ | 2<sup >30</sup > | | 20 |
431+ | (2<sup >30</sup >) - 1 | | 5 |
432+ | ... | ... | ... |
433+ | 10 | e | → 9 |
434+ | 9 | d | → (2<sup >30</sup >) - 1 |
435+ | 8 | c | 5 |
436+ | 7 | b | → 4 |
437+ | 6 | a | → 0 |
438+ | 5 | z | → 4 |
439+ | 4 | y | 10 |
440+ | 3 | x | → 0 |
441+ | 2 | j | → 0 |
442+ | 1 | i | → 2<sup >30</sup > |
443+ | 0 | h | 3 |
444444
445445We end up allocating another value on the heap, and so we have to subtract one
446446from 2<sup >30</sup >. It’s easier to just write that than ` 1,073,741,823 ` . In any
447447case, we set up the variables as usual.
448448
449449At the end of ` bar() ` , it calls ` baz() ` :
450450
451- | Address | Name | Value |
452- | ----------------------| ------| ----------------------|
453- | 2<sup >30</sup > | | 20 |
454- | (2<sup >30</sup >) - 1 | | 5 |
455- | ... | ... | ... |
456- | 12 | g | 100 |
457- | 11 | f | 9 |
458- | 10 | e | 9 |
459- | 9 | d | (2<sup >30</sup >) - 1 |
460- | 8 | c | 5 |
461- | 7 | b | 4 |
462- | 6 | a | 0 |
463- | 5 | z | 4 |
464- | 4 | y | 10 |
465- | 3 | x | 0 |
466- | 2 | j | 0 |
467- | 1 | i | 2<sup >30</sup > |
468- | 0 | h | 3 |
451+ | Address | Name | Value |
452+ | ----------------------| ------| ------------------------ |
453+ | 2<sup >30</sup > | | 20 |
454+ | (2<sup >30</sup >) - 1 | | 5 |
455+ | ... | ... | ... |
456+ | 12 | g | 100 |
457+ | 11 | f | → 9 |
458+ | 10 | e | → 9 |
459+ | 9 | d | → (2<sup >30</sup >) - 1 |
460+ | 8 | c | 5 |
461+ | 7 | b | → 4 |
462+ | 6 | a | → 0 |
463+ | 5 | z | → 4 |
464+ | 4 | y | 10 |
465+ | 3 | x | → 0 |
466+ | 2 | j | → 0 |
467+ | 1 | i | → 2<sup >30</sup > |
468+ | 0 | h | 3 |
469469
470470With this, we’re at our deepest point! Whew! Congrats for following along this
471471far.
472472
473473After ` baz() ` is over, we get rid of ` f ` and ` g ` :
474474
475- | Address | Name | Value |
476- | ----------------------| ------| ----------------------|
477- | 2<sup >30</sup > | | 20 |
478- | (2<sup >30</sup >) - 1 | | 5 |
479- | ... | ... | ... |
480- | 10 | e | 9 |
481- | 9 | d | (2<sup >30</sup >) - 1 |
482- | 8 | c | 5 |
483- | 7 | b | 4 |
484- | 6 | a | 0 |
485- | 5 | z | 4 |
486- | 4 | y | 10 |
487- | 3 | x | 0 |
488- | 2 | j | 0 |
489- | 1 | i | 2<sup >30</sup > |
490- | 0 | h | 3 |
475+ | Address | Name | Value |
476+ | ----------------------| ------| ------------------------ |
477+ | 2<sup >30</sup > | | 20 |
478+ | (2<sup >30</sup >) - 1 | | 5 |
479+ | ... | ... | ... |
480+ | 10 | e | → 9 |
481+ | 9 | d | → (2<sup >30</sup >) - 1 |
482+ | 8 | c | 5 |
483+ | 7 | b | → 4 |
484+ | 6 | a | → 0 |
485+ | 5 | z | → 4 |
486+ | 4 | y | 10 |
487+ | 3 | x | → 0 |
488+ | 2 | j | → 0 |
489+ | 1 | i | → 2<sup >30</sup > |
490+ | 0 | h | 3 |
491491
492492Next, we return from ` bar() ` . ` d ` in this case is a ` Box<T> ` , so it also frees
493493what it points to: (2<sup >30</sup >) - 1.
494494
495- | Address | Name | Value |
496- | -----------------| ------| ----------------|
497- | 2<sup >30</sup > | | 20 |
498- | ... | ... | ... |
499- | 5 | z | 4 |
500- | 4 | y | 10 |
501- | 3 | x | 0 |
502- | 2 | j | 0 |
503- | 1 | i | 2<sup >30</sup > |
504- | 0 | h | 3 |
495+ | Address | Name | Value |
496+ | -----------------| ------| ------------------ |
497+ | 2<sup >30</sup > | | 20 |
498+ | ... | ... | ... |
499+ | 5 | z | → 4 |
500+ | 4 | y | 10 |
501+ | 3 | x | → 0 |
502+ | 2 | j | → 0 |
503+ | 1 | i | → 2<sup >30</sup > |
504+ | 0 | h | 3 |
505505
506506And after that, ` foo() ` returns:
507507
508- | Address | Name | Value |
509- | -----------------| ------| ----------------|
510- | 2<sup >30</sup > | | 20 |
511- | ... | ... | ... |
512- | 2 | j | 0 |
513- | 1 | i | 2<sup >30</sup > |
514- | 0 | h | 3 |
508+ | Address | Name | Value |
509+ | -----------------| ------| ------------------ |
510+ | 2<sup >30</sup > | | 20 |
511+ | ... | ... | ... |
512+ | 2 | j | → 0 |
513+ | 1 | i | → 2<sup >30</sup > |
514+ | 0 | h | 3 |
515515
516516And then, finally, ` main() ` , which cleans the rest up. When ` i ` is ` Drop ` ped,
517517it will clean up the last of the heap too.
0 commit comments