πŸ’©

programierds

PROGRAMIERDS_OS v1.0.4 // TOPIC: C_MEMORY

> Pass by Value

and Reference

In C, everything is passed by value. Pointers make it seem like magic, but they are still copies of addresses.

VALUE
direct copy
REFERENCE
memory address

↓ scroll to continue


FUNDAMENTAL

Stack vs Heap

First understand how C organizes memory. Without this, nothing that follows makes sense.

STACK

Local variables and references. LIFO.

int x 42
boolean b true
int[] nums → 0x4A2F
Persona p → 0x8C1D

Primitives: the value lives here.
Objects: only the address (reference).

HEAP

Real objects. Managed by the GC.

0x4A2F
int[ ]
[ 1, 2, 3 ]
0x8C1D
Persona
nombre: "Ana"
0x3F0B
char *
"Hola"

Real objects live here.
The Stack holds the address to reach them.

THE FUNDAMENTAL RULE

When C passes something to a function, what travels is the content of the variable on the Stack. For primitives, that is the direct value. For objects, that is the memory address (the reference). In BOTH cases: it is copied.


CASE 01

Pass by Value

With primitives (int, double, boolean, char...)

void cambiar(int x) {
  x = 99;
  // x es una COPIA local
}

int a = 5;
cambiar(a);
printf("%d\n", a); // 5 ← no cambió

WHY

C copies the value 5 into a new variable x. Any change to x is local to the method. a is never touched.

VISUALIZATION

a
5
───> copy
x (copy)
5

x changes to 99...

...but a is still 5  


CASE 02 β€” THE TRICKY

Objects: The Reference is Copied

Both variables point to the SAME object in the heap

void modificar(int[] arr) {
  arr[0] = 99;
  // arr apunta al MISMO objeto
}

int[] nums = {1,2,3};
modificar(nums);
printf("%d\n", nums[0]); // 99!

WHY

arr receives a COPY of the reference (the address 0x4A2F). Both point to the same array in the heap. Modifying arr[0] modifies the real object, and nums sees it.

MEMORY DIAGRAM

STACK
nums → 0x4A2F
arr (copy) → 0x4A2F
HEAP
0x4A2F
[ 1, 2, 3 ]
arr[0] = 99 → nums[0] == 99

CASE 03 β€” THE TEST

Reassigning the Reference

This proves THAT C copies pointers by value

void reasignar(int[] arr) {
  arr = new int[]{99,99,99};
  // arr ahora apunta a OTRO objeto
  // nums NO se entera
}

int[] nums = {1,2,3};
reasignar(nums);
printf("%d\n", nums[0]); // 1 ← no cambió

THE KEY

arr = new int[]... only changes where the local COPY points. The original reference nums in the caller's Stack is not modified. It still points to the original object. This is the proof that in C pointers are also passed BY VALUE.

DIAGRAM

STACK
nums → 0x4A2F
arr (copy) → 0x4A2F
HEAP
0x4A2F
[1, 2, 3]
← nums points here
0x9E3C
[99,99,99]
← arr reassigned
nums[0] is still 1

CASE 04

Person Class

Modifying fields vs reassigning the object

✓ Modify the field

class Persona {
  char nombre[20];
}

void cambiarNombre(Persona p) {
  p.nombre = "Nuevo";
}

Persona ana = new Persona();
ana.nombre = "Ana";
cambiarNombre(ana);
// ana.nombre == "Nuevo" ✓

RESULT

p points to the same object as ana. Modifying p.nombre changes the shared object.

✗ Reassign the reference

void reemplazar(Persona p) {
  p = new Persona();
  p.nombre = "Otro";
  // p apunta a un objeto nuevo
}

Persona ana = new Persona();
ana.nombre = "Ana";
reemplazar(ana);
// ana.nombre == "Ana" (sin cambios)

RESULT

The local copy p points to another object. ana still points to the original.


SPECIAL CASE

Strings in C: Mutable Arrays

In C, a char[] array can be modified character by character if you have writable memory.

void cambiar(char s[]) {
  s[0] = 'Z';
  // modifica el arreglo original
}

char nombre[] = "Ana";
cambiar(nombre);
printf("%s\n", nombre); // "Zna"

IMMUTABILITY

char[] in C is mutable if the memory is writable. s[0] = 'Z' modifies the same received array. The function writes directly on the same shared memory.

CHAR ARRAY

Literals are often read-only; if you want to mutate them, use your own char array. Use strcmp() to compare content, don't compare addresses if you want to know if they say the same.

WHAT HAPPENS IN MEMORY

STACK
nombre → 0xA1B2  ✓
s (copy) → 0xC3D4 (new)
HEAP
0xA1B2 (buffer char[])
"Ana"
original, immutable
0xC3D4
"Nuevo"
new object
nombre is still "Ana"

SNAPSHOT

Complete Memory Diagram

Everything together. Primitives and references in action.

STACK
int edad 25
double sueldo 3500.0
boolean activo true
char nombre[] → 0xA1B2
int[] scores → 0x4A2F
Persona p → 0x8C1D
primitives: direct value   objects: address
HEAP
0xA1B2
char[]
"Ana"
0x4A2F
int[]
[90, 85, 78]
0x8C1D
Persona
nombre: → 0xA1B2
edad: 25

Objects do not live in the Stack.
Only the address to find them.

NOTE ABOUT PRIMITIVES

Primitives (int, double, boolean, char, long, float, short, byte) are the ONLY ones that live directly on the Stack. Everything else β€” including dynamic buffers, arrays allocated on the heap, and structs managed with pointers β€” lives on the Heap.


SYNTHESIS

Golden Rules

Write them down. They are immutable.

01

C ALWAYS passes by value

No exceptions. Pointers don't change this rule: they just copy addresses.

02

For primitives: the VALUE is copied

The method receives a copy. Changing it does not affect the original.

03

For objects: the REFERENCE is copied

The copy contains the same memory address. Both point to the same object.

04

Modifying the object through the copy: DOES affect the original

arr[0] = 99, p.nombre = "X" — both references see the change.

05

Reassigning the copied reference: does NOT affect the original

arr = new int[]..., p = new Persona() — only moves the local copy.


ESTADO: SESION_COMPLETADA

SESSION COMPLETED

Now you know the difference between pass by value and use of pointers in C.
Don't confuse it with "pass by reference" from other languages.

PRIMITIVES

int, double, boolean, char, long, float, short, byte

→ copy of the value

OBJECTS

punteros, arrays, structs

→ copy of the reference

END OF SESSION // DATA PROCESSED CORRECTLY

← BACK TO PRESENTATIONS