Memory Management

Pass by Value vs Pass by Reference

Comparing parameter passing behavior across C, JavaScript, Python, and Java.

SLIDE 1 / 6

1. How are arguments passed to functions?

When invoking a function, arguments are either copied by value or share a direct memory reference.

Pass by Value: Function receives an independent copy. Modifying the parameter DOES NOT alter original.
Pass by Reference: Function receives an alias to caller variable. Any change mutates the caller value.
STACK MEMORY LAYOUT
Stack Frame: main()
x = 100x7FF01
⬇️ Value Copy
Stack Frame: update(val)
val = 10Isolated Copy

2. C: Strict Pass-by-Value & Pointers

In C EVERYTHING is pass-by-value. To modify an external variable, we pass the memory address (`&var`) by value.

  • swap(int a, int b): Swaps local copies, no effect in main.
  • swap(int *a, int *b): Dereferences addresses to modify caller memory.
pointers.c
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;  // Modifica memoria original
    *b = temp;
}

int main() {
    int x = 5, y = 10;
    swap(&x, &y); // x=10, y=5
}

3. Java: Always Pass-by-Value (Primitives vs References)

Java is ALWAYS pass-by-value. For primitives it copies the value. For objects it copies the reference handle.

Mutar atributos: Affects the Heap object.
Reasignar referencia: Only updates local handle copy, not original caller handle.
PassTest.java
public static void modify(Dog d) {
    d.setName("Rex"); // Mutación en Heap
    d = new Dog("Fido"); // No afecta al caller
}

4. JavaScript: Call-by-Sharing (Reference Copy)

Primitives in JS are immutable and passed by value. Objects and arrays are passed by reference copy.

  • obj.prop = val: Mutates actual object.
  • obj = {}: Rebinds function-local variable only.
app.js
function update(user) {
    user.age = 30;     // Objeto original actualizado
    user = { age: 99 }; // Sin efecto fuera
}
const u = { age: 20 };
update(u); // u.age es 30

5. Python: Pass-by-Assignment

In Python arguments are passed by assignment. The function binds a local name to the received object.

list.append(): In-place mutation in Heap.
lst = lst + [x]: Creates a new object and rebinds local name.
script.py
def process(lst):
    lst.append(100) # Mutación real
    lst = [1, 2]    # Re-binding local

data = [1]
process(data) # data es [1, 100]

6. Live Call Stack Simulator

Test parameter passing behavior across languages:

C: swap(&a, &b) Execution Trace
Paso 1: main() crea `a=5` (0x10) y `b=10` (0x14). Pasa direcciones `&a` y `&b`.
[main frame: a=5, b=10] -> [swap frame: *a=>0x10, *b=>0x14]
Caller result: a=10, b=5 (Successful Mutation)