Swift
memory management
stack
heap
programming concepts

Swift stack and heap understanding

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Swift memory discussions often start with a shortcut: structs use the stack and classes use the heap. That shortcut is useful for intuition, but it is not the real model. In Swift, value semantics, reference semantics, and ARC are more important than assuming a specific storage location.

What stack and heap really mean

The stack stores short-lived call frame data. It is fast because values can be pushed and removed in a strict order as functions enter and return. Each thread has its own stack.

The heap is used for data whose lifetime cannot be tied to one stack frame. Heap allocation is more flexible, but it requires bookkeeping and shared ownership management. In Swift, class instances are typically heap allocated and managed with automatic reference counting.

That leads to an important distinction. Stack versus heap describes storage strategy. Value versus reference describes program behavior. Those ideas are related, but they are not the same rule.

Value types and reference types

Structs and enums are value types. Classes are reference types. Assigning a value type creates an independent value. Assigning a reference type copies a reference to the same underlying object.

swift
1struct Point {
2    var x: Int
3    var y: Int
4}
5
6final class Counter {
7    var value: Int
8
9    init(value: Int) {
10        self.value = value
11    }
12}
13
14var firstPoint = Point(x: 1, y: 2)
15var secondPoint = firstPoint
16secondPoint.x = 99
17
18print(firstPoint.x)  // 1
19print(secondPoint.x) // 99
20
21let firstCounter = Counter(value: 1)
22let secondCounter = firstCounter
23secondCounter.value = 99
24
25print(firstCounter.value)  // 99
26print(secondCounter.value) // 99

This is the behavior Swift developers should reason about first. Whether the compiler places a particular value on the stack, in registers, or somewhere else is an implementation detail unless you are deep in profiling work.

Why the simple rule breaks down

Even value types are not guaranteed to live only on the stack. Swift can optimize storage based on how a value is used. Some value types also use heap-backed storage internally. Array, String, and Dictionary are common examples.

They still behave like values because Swift uses copy-on-write. Two variables may temporarily share storage, but once one side mutates, Swift creates independent state.

swift
1var numbers = [1, 2, 3]
2var moreNumbers = numbers
3
4moreNumbers.append(4)
5
6print(numbers)     // [1, 2, 3]
7print(moreNumbers) // [1, 2, 3, 4]

This is why "struct means stack" is too blunt to be reliable. The public semantics are value-based even when the implementation uses heap storage under the hood.

Where ARC matters

ARC tracks strong references to class instances. When the last strong reference disappears, Swift deinitializes the object and releases its memory. That makes heap management automatic, but it also means class-heavy designs can introduce retain cycles or longer-than-expected object lifetimes if ownership is unclear.

In real Swift code, choose structs when values should be copied and reasoned about independently. Choose classes when identity and shared mutable state are intentional. Then profile before making performance claims about stack and heap.

Common Pitfalls

  • Treating stack versus heap as the main design rule instead of value versus reference semantics.
  • Assuming every struct always lives on the stack with no exceptions.
  • Forgetting that collection types like Array can use heap-backed storage while still acting like values.
  • Choosing classes by default for small data models that should behave independently.
  • Blaming performance on allocation strategy before measuring the real hot path.

Summary

  • Stack and heap describe storage, while value and reference describe behavior.
  • Structs and enums are value types; classes are reference types managed by ARC.
  • Value types are not guaranteed to live only on the stack.
  • Standard library collections often combine value semantics with heap-backed storage and copy-on-write.
  • Design around ownership and semantics first, then profile before optimizing low-level memory behavior.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.