@@ -217,12 +217,12 @@ on the heap. The actual value of the box is a structure which has a pointer to
217
217
it allocates some memory for the heap, and puts ` 5 ` there. The memory now looks
218
218
like this:
219
219
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 > |
226
226
227
227
We have 2<sup >30</sup > in our hypothetical computer with 1GB of RAM. And since
228
228
our 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
242
242
layout of a program which has been running for a while now:
243
243
244
244
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 > |
256
256
257
257
In this case, we’ve allocated four things on the heap, but deallocated two of
258
258
them. There’s a gap between 2<sup >30</sup > and (2<sup >30</sup >) - 3 which isn’t
@@ -304,22 +304,22 @@ fn main() {
304
304
305
305
When we enter ` main() ` , memory looks like this:
306
306
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 |
311
311
312
312
` x ` is a plain old ` 5 ` , and ` y ` is a reference to ` x ` . So its value is the
313
313
memory location that ` x ` lives at, which in this case is ` 0 ` .
314
314
315
315
What about when we call ` foo() ` , passing ` y ` as an argument?
316
316
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 |
323
323
324
324
Stack frames aren’t just for local bindings, they’re for arguments too. So in
325
325
this case, we need to have both ` i ` , our argument, and ` z ` , our local variable
@@ -366,152 +366,152 @@ fn main() {
366
366
367
367
First, we call ` main() ` :
368
368
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 |
376
376
377
377
We allocate memory for ` j ` , ` i ` , and ` h ` . ` i ` is on the heap, and so has a
378
378
value pointing there.
379
379
380
380
Next, at the end of ` main() ` , ` foo() ` gets called:
381
381
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 |
392
392
393
393
Space gets allocated for ` x ` , ` y ` , and ` z ` . The argument ` x ` has the same value
394
394
as ` j ` , since that’s what we passed it in. It’s a pointer to the ` 0 ` address,
395
395
since ` j ` points at ` h ` .
396
396
397
397
Next, ` foo() ` calls ` baz() ` , passing ` z ` :
398
398
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 |
411
411
412
412
We’ve allocated memory for ` f ` and ` g ` . ` baz() ` is very short, so when it’s
413
413
over, we get rid of its stack frame:
414
414
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 |
425
425
426
426
Next, ` foo() ` calls ` bar() ` with ` x ` and ` z ` :
427
427
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 |
444
444
445
445
We end up allocating another value on the heap, and so we have to subtract one
446
446
from 2<sup >30</sup >. It’s easier to just write that than ` 1,073,741,823 ` . In any
447
447
case, we set up the variables as usual.
448
448
449
449
At the end of ` bar() ` , it calls ` baz() ` :
450
450
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 |
469
469
470
470
With this, we’re at our deepest point! Whew! Congrats for following along this
471
471
far.
472
472
473
473
After ` baz() ` is over, we get rid of ` f ` and ` g ` :
474
474
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 |
491
491
492
492
Next, we return from ` bar() ` . ` d ` in this case is a ` Box<T> ` , so it also frees
493
493
what it points to: (2<sup >30</sup >) - 1.
494
494
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 |
505
505
506
506
And after that, ` foo() ` returns:
507
507
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 |
515
515
516
516
And then, finally, ` main() ` , which cleans the rest up. When ` i ` is ` Drop ` ped,
517
517
it will clean up the last of the heap too.
0 commit comments