Basic Memory Diagrams in Function Calls
Table of Contents
- 1. Overview
- 2. Source Code
- 3. Line-by-line trace of code
- 3.1. Initial Call to Main, Local Symboliables defined
- 3.2. Call to
doubler1(r)
- 3.3.
doubler1(r)
executes - 3.4.
doubler1(r)
completes - 3.5.
main()
printsr
- 3.6. Control back in
main()
- 3.7. Call to
doubler2(s)
- 3.8.
doubler2(s)
executes - 3.9.
doubler2(s)
completes - 3.10.
main()
printss[0]
- 3.11. Control back in
main()
- 3.12.
main()
completes
1 Overview
This document gives a brief overview of the function call stack and
memory heap. It shows a key difference between passing a primitive
argument to a function like an int
versus passing a reference to a
function.
2 Source Code
1 public class Doubler{ 2 public static void doubler1(int x){ 3 x = 2*x; 4 } 5 public static void doubler2(int x[]){ 6 x[0] = 2*x[0]; 7 } 8 public static void main(String args[]){ 9 int r = 10; 10 int s[] = {10}; 11 12 doubler1(r); 13 System.out.println("r: "+r); 14 15 doubler2(s); 16 System.out.println("s[0]: "+s[0]); 17 } 18 } Compile/Run > javac Doubler.java > java Doubler r: 10 s[0]: 20
The central question in the code above is why the function
doubler1(int)
does not seem to change the value of r
while the
function doubler2(int [])
does change the value of s[0]
. This is
best understood by examining the memory layout on the stack and heap
of the running main
method. Observer in the trace below how a
"copy" of r
is passed to doubler1()
which is changed then
discarded while a reference to the location of array s
is passed to
doubler2()
enabling the array to actually be changed.
3 Line-by-line trace of code
3.1 Initial Call to Main, Local Symboliables defined
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 10 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.2 Call to doubler1(r)
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 12 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
doubler1 | 2 | x | 1036 | 10 | Call to doubler1 |
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.3 doubler1(r)
executes
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 12 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
doubler1 | 3 | x | 1036 | 20 | |
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.4 doubler1(r)
completes
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 12 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.5 main()
prints r
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 13 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
println() | ?? | x | 1036 | 10 | "10" put on screen |
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.6 Control back in main()
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 15 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.7 Call to doubler2(s)
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 15 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
doubler2() | 5 | x | 1036 | 4024 | Pass reference to s |
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 10 |
3.8 doubler2(s)
executes
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 15 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
doubler2() | 6 | x | 1036 | 4024 | |
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 20 |
3.9 doubler2(s)
completes
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 15 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 20 |
3.10 main()
prints s[0]
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 16 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
println() | ?? | x | 1036 | 20 | "20" put on screen |
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 20 |
3.11 Control back in main()
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
… | … | … | … | ||
main() | 16 | args | 1024 | 5096 | Top of the Stack |
r | 1028 | 10 | |||
s | 1032 | 4024 | |||
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 20 |
3.12 main()
completes
Method | Line | Symbol | Addr | Value | Notes |
---|---|---|---|---|---|
.. | … | Heap Memory | |||
length | 4020 | 1 | |||
4024 | 20 |