1

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!

9
  • Not really but you are printing the local variable so I guess the same memory is being reused. Printing the stored propety cars will give you unique addresses. Commented Dec 5, 2020 at 18:37
  • Yeah I assumed the same, just curious if this behaviour is the result some memory optimization. Commented Dec 5, 2020 at 18:38
  • 2
    The compiler can also create a temporary variable with the contents of cars[0] and pass that address to the function. Commented Dec 5, 2020 at 18:40
  • @MartinR Hmmm, I tried cars.withUnsafeBufferPointer { bp in bp.baseAddress!.advanced(by: 0))), trying to replicate the semantics that &cars[0] would have in C (it would be a pointer expression equivalent to (cars + 0), i.e. a pointer into the buffer), yet I still get the same address both times. Why could that be? Commented Dec 5, 2020 at 20:44
  • 2
    Yes, this the kind of memory optimization a modern compiler is supposed to do. The two Garage instances are not used at the same time. So it would be a waste of memory to allocate them in separate locations on the stack. Commented Dec 5, 2020 at 21:31

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.