@@ -217,18 +217,18 @@ 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 > |
226
-
227
- We have 2<sup >30</sup > in our hypothetical computer with 1GB of RAM. And since
220
+ | Address | Name | Value |
221
+ | ---------------------- | ------| ------ ------------------|
222
+ | ( 2<sup >30</sup >) - 1 | | 5 |
223
+ | ... | ... | ... |
224
+ | 1 | y | 42 |
225
+ | 0 | x | → ( 2<sup >30</sup >) - 1 |
226
+
227
+ We have ( 2<sup >30</sup >) - 1 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
229
229
other end. So our first value is at the highest place in memory. And the value
230
230
of the struct at ` x ` has a [ raw pointer] [ rawpointer ] to the place we’ve
231
- allocated on the heap, so the value of ` x ` is 2<sup >30</sup >, the memory
231
+ allocated on the heap, so the value of ` x ` is ( 2<sup >30</sup >) - 1 , the memory
232
232
location we’ve asked for.
233
233
234
234
[ rawpointer ] : raw-pointers.html
@@ -244,18 +244,18 @@ layout of a program which has been running for a while now:
244
244
245
245
| Address | Name | Value |
246
246
| ----------------------| ------| ------------------------|
247
- | 2<sup >30</sup > | | 5 |
248
- | (2<sup >30</sup >) - 1 | | |
247
+ | (2<sup >30</sup >) - 1 | | 5 |
249
248
| (2<sup >30</sup >) - 2 | | |
250
- | (2<sup >30</sup >) - 3 | | 42 |
249
+ | (2<sup >30</sup >) - 3 | | |
250
+ | (2<sup >30</sup >) - 4 | | 42 |
251
251
| ... | ... | ... |
252
- | 3 | y | → (2<sup >30</sup >) - 3 |
252
+ | 3 | y | → (2<sup >30</sup >) - 4 |
253
253
| 2 | y | 42 |
254
254
| 1 | y | 42 |
255
- | 0 | x | → 2<sup >30</sup > |
255
+ | 0 | x | → ( 2<sup >30</sup >) - 1 |
256
256
257
257
In this case, we’ve allocated four things on the heap, but deallocated two of
258
- them. There’s a gap between 2<sup >30</sup > and (2<sup >30</sup >) - 3 which isn’t
258
+ them. There’s a gap between ( 2<sup >30</sup >) - 1 and (2<sup >30</sup >) - 4 which isn’t
259
259
currently being used. The specific details of how and why this happens depends
260
260
on what kind of strategy you use to manage the heap. Different programs can use
261
261
different ‘memory allocators’, which are libraries that manage this for you.
@@ -366,105 +366,105 @@ 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 >) - 1 | | 20 |
372
+ | ... | ... | ... |
373
+ | 2 | j | → 0 |
374
+ | 1 | i | → ( 2<sup >30</sup >) - 1 |
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 >) - 1 | | 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 >) - 1 |
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 >) - 1 | | 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 >) - 1 |
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 >) - 1 | | 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 >) - 1 |
424
+ | 0 | h | 3 |
425
425
426
426
Next, ` foo() ` calls ` bar() ` with ` x ` and ` z ` :
427
427
428
428
| Address | Name | Value |
429
429
| ----------------------| ------| ------------------------|
430
- | 2<sup >30</sup > | | 20 |
431
- | (2<sup >30</sup >) - 1 | | 5 |
430
+ | ( 2<sup >30</sup >) - 1 | | 20 |
431
+ | (2<sup >30</sup >) - 2 | | 5 |
432
432
| ... | ... | ... |
433
433
| 10 | e | → 9 |
434
- | 9 | d | → (2<sup >30</sup >) - 1 |
434
+ | 9 | d | → (2<sup >30</sup >) - 2 |
435
435
| 8 | c | 5 |
436
436
| 7 | b | → 4 |
437
437
| 6 | a | → 0 |
438
438
| 5 | z | → 4 |
439
439
| 4 | y | 10 |
440
440
| 3 | x | → 0 |
441
441
| 2 | j | → 0 |
442
- | 1 | i | → 2<sup >30</sup > |
442
+ | 1 | i | → ( 2<sup >30</sup >) - 1 |
443
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
- from 2<sup >30</sup >. It’s easier to just write that than ` 1,073,741,823 ` . In any
446
+ from ( 2<sup >30</sup >) - 1 . It’s easier to just write that than ` 1,073,741,822 ` . 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
451
| Address | Name | Value |
452
452
| ----------------------| ------| ------------------------|
453
- | 2<sup >30</sup > | | 20 |
454
- | (2<sup >30</sup >) - 1 | | 5 |
453
+ | ( 2<sup >30</sup >) - 1 | | 20 |
454
+ | (2<sup >30</sup >) - 2 | | 5 |
455
455
| ... | ... | ... |
456
456
| 12 | g | 100 |
457
457
| 11 | f | → 9 |
458
458
| 10 | e | → 9 |
459
- | 9 | d | → (2<sup >30</sup >) - 1 |
459
+ | 9 | d | → (2<sup >30</sup >) - 2 |
460
460
| 8 | c | 5 |
461
461
| 7 | b | → 4 |
462
462
| 6 | a | → 0 |
463
463
| 5 | z | → 4 |
464
464
| 4 | y | 10 |
465
465
| 3 | x | → 0 |
466
466
| 2 | j | → 0 |
467
- | 1 | i | → 2<sup >30</sup > |
467
+ | 1 | i | → ( 2<sup >30</sup >) - 1 |
468
468
| 0 | h | 3 |
469
469
470
470
With this, we’re at our deepest point! Whew! Congrats for following along this
@@ -474,44 +474,44 @@ After `baz()` is over, we get rid of `f` and `g`:
474
474
475
475
| Address | Name | Value |
476
476
| ----------------------| ------| ------------------------|
477
- | 2<sup >30</sup > | | 20 |
478
- | (2<sup >30</sup >) - 1 | | 5 |
477
+ | ( 2<sup >30</sup >) - 1 | | 20 |
478
+ | (2<sup >30</sup >) - 2 | | 5 |
479
479
| ... | ... | ... |
480
480
| 10 | e | → 9 |
481
- | 9 | d | → (2<sup >30</sup >) - 1 |
481
+ | 9 | d | → (2<sup >30</sup >) - 2 |
482
482
| 8 | c | 5 |
483
483
| 7 | b | → 4 |
484
484
| 6 | a | → 0 |
485
485
| 5 | z | → 4 |
486
486
| 4 | y | 10 |
487
487
| 3 | x | → 0 |
488
488
| 2 | j | → 0 |
489
- | 1 | i | → 2<sup >30</sup > |
489
+ | 1 | i | → ( 2<sup >30</sup >) - 1 |
490
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
- what it points to: (2<sup >30</sup >) - 1 .
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 |
493
+ what it points to: (2<sup >30</sup >) - 2 .
494
+
495
+ | Address | Name | Value |
496
+ | ---------------------- | ------| ------ ------------------|
497
+ | ( 2<sup >30</sup >) - 1 | | 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 >) - 1 |
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 >) - 1 | | 20 |
511
+ | ... | ... | ... |
512
+ | 2 | j | → 0 |
513
+ | 1 | i | → ( 2<sup >30</sup >) - 1 |
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