[Swift] Memory Safety

Lena·2020년 12월 23일
0
post-custom-banner

Memory Safety

Swift는 기본적으로 코드 상의 안전하지 않은 행위를 막아줍니다. 예를 들면 variables이 initialize되기 이전에 사용되는 것을 막고, 메모리가 해제(deallocated)된 이후에는 접근하지 않으며, array의 index가 범위를 벗어나지 않는지 체크해줍니다.

Swift는 같은 메모리 공간을 동시 접근해서 충돌이 발생하는 것을 막아줍니다. Swift가 메모리 관리를 자동으로 해주기 때문에 대부분의 경우 memory에 접근하는 것을 고려할 필요가 없지만, 잠재적으로 memory 충돌이 발생할 수 있는 상황을 이해하는 것은 중요합니다.

Understanding Conflicting Access to Memory

동시 접근(Overlapping accesses)은 주로 inout parameter를 사용한 function 또는 구조체의 methods or mutating methods 사용에서 발생합니다.

Conflicting Access to In-Out Parameters

For example:

var stepSize = 1

func increment(_ number: inout Int) { // write access
    number += stepSize // read access
}

increment(&stepSize)
// Error: conflicting accesses to stepSize

numberinout parameter이므로 function 호출 시 write access로 메모리를 참조합니다.
function 내부에서 stepSize가 read access 하기 위해 메모리에 접근하나, write access와 같은 메모리 위치를 참조하면서(overlap) 메모리 충돌이 발생합니다(conflict).

Conflicting Access to self in Methods

A mutating method on a structure has write access to self for the duration of the method call. For example, consider a game where each player has a health amount, which decreases when taking damage, and an energy amount, which decreases when using special abilities.

struct Player {
    var name: String
    var health: Int
    var energy: Int

    static let maxHealth = 10
    mutating func restoreHealth() {
        health = Player.maxHealth
    }
}

func balance(_ x: inout Int, _ y: inout Int) {
    let sum = x + y
    x = sum / 2
    y = sum - x
}

extension Player {
    mutating func shareHealth(with teammate: inout Player) {
        balance(&teammate.health, &health)
    }
}

var oscar = Player(name: "Oscar", health: 10, energy: 10)
var maria = Player(name: "Maria", health: 5, energy: 10)
oscar.shareHealth(with: &maria)  // OK

위 예제는 memory conflict를 발생시키지 않는데, balance 함수가 호출되면서 2개의 inout parameter가 write access로 메모리를 참조하지만 서로 다른 위치의 메모리에 접근하므로 충돌이 발생하지 않습니다.

하지만, oscar를 함수의 인자로 전달하면 conflict가 발생합니다.

oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar

mutating method는 self의 write access가 필요한데, inout parameter로 selfoscar를 전달하게 되면 같은 메모리 위치를 참조하게 되므로, 두 write access는 충돌하게 됩니다.

Reference

Memory Safety

post-custom-banner

0개의 댓글