Search code examples
swiftmemory-addressvalue-type

Weird memory behaviour with array of structs


I am seeing a very weird (or at least weird to me) behaviour regarding memory addresses when playing around with structs in Swift.

I have the following code in a Playground:

func address(o: UnsafeRawPointer) -> Int {
    return Int(bitPattern: o)
}

struct Car {}

struct Garage {
    
    let cars: [Car]

    init() {
        var cars = [Car]()
        for _ in 0..<2 {
            cars.append(Car())
        }
        print(NSString(format: "%p", address(o: &cars[0])))
        self.cars = cars
    }
    
}

_ = Garage()
_ = Garage()

The console prints the same memory address both times for the first element of the cars array, even though they are initialized in completely different Garage instances:

0x7fff2f1102e0
0x7fff2f1102e0

Could someone shed some light on what's happening here?

Thanks!


Solution

  • The printed addresses are hint: 0x7fff2f1102e0 is likely a stack address, not the address of an object on the heap.

    So does Swift allocate the Car array on the stack? No it doesn't.

    However, cars[0] is an operation that returns a copy of the Car instance. That's because Car is a struct and has value semantics. And the copy is on the stack.

    So address(o: &cars[0]) returns the address of the copied instance on the stack. Since two consecutive calls of init() are likely to use the stack in the same way, they will return the same address.